summaryrefslogtreecommitdiff
path: root/src/lib/aplwc_internal.h
blob: 148fd589a0ef1650f2d0ea0e4bd0ceedcbbb2b37 (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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/* 
 * 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>

typedef int symbol_t;

enum keyword {
	KW_MODULE,
	KW_SYMBOL,
	KW_EXPORT
};

#define N_KWDS KW_EXPORT+1

struct aplwc {
	struct aplwc_fns fns;
	enum aplwc_rc last_error;
	struct aplwc_module *modules;
	struct symbol *symtab;
	symbol_t keyword_symbols[N_KWDS];

	/* 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[FLEXIBLE_ARRAY_MEMBER];
};

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;
	union {
		symbol_t symbol;
		enum keyword keyword;
	} data;
};

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

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 module_member *imports;
	struct module_member *members;
	struct aplwc_module *link;
};

struct module_member {
	int exported;
	struct aplwc_module *module;
	symbol_t name;
	struct module_member *real_member; /* a symbol points to its identifier member. An imported symbol points to the defining member */
	struct module_member *link;
};

struct symbol {
	symbol_t id;
	struct string *text;
	struct symbol *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_member *memory_alloc_module_member(struct aplwc *);
struct symbol *memory_alloc_symbol(struct aplwc *);
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 */
#define INVALID_CHAR UINT32_MAX
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 *);
struct string *substring(struct aplwc *, struct string *, size_t, size_t);

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

/* symtab.c */
enum aplwc_rc getsym(struct aplwc *, struct string *, symbol_t *);

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

/* unicode.c */
int is_id_start(uint32_t);
int is_id_continue(uint32_t);
int is_pattern_syntax(uint32_t);

#endif /* APLWC_INTERNAL_H */