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
|
/*
* Functions for constructing/accessing the Abstract Syntax Tree.
*
* Copyright © 2025 Samuel Lidén Borell <samuel@kodafritt.se>
*
* SPDX-License-Identifier: EUPL-1.2+
*/
#include <string.h>
#include "compiler.h"
#include "token.h"
struct Module *module, *modules;
struct Type *current_type;
struct Func *current_func;
static struct Type **type_nextptr, **inner_type_nextptr;
static struct Func **func_nextptr;
static struct Func **type_func_nextptr, **innertype_func_nextptr;
void module_start(void)
{
struct Module *mod = malloc(sizeof(struct Module));
NO_NULL(mod);
mod->types = NULL;
mod->funcs = NULL;
mod->types_list = NULL;
mod->funcs_list = NULL;
mod->next = modules;
modules = mod;
module = mod;
current_type = NULL;
current_func = NULL;
type_nextptr = &module->types_list;
func_nextptr = &module->funcs_list;
}
struct Type *map_named_type(const char *name, size_t len)
{
struct TreeNode **root;
struct Type *t;
/* If inside an type definition, then the sought type might be an
inner/nested type defined later within the type being defined.
So in that case we ONLY search among the inner types at this point,
and only at the end we can search among the top-level types. */
/* XXX could perhaps require that inner types start with an underscore? */
root = (current_type ?
¤t_type->inner_types :
&module->types);
t = (struct Type *)tree_insert_str(root,
name, len, NULL, sizeof(struct Type));
if (!t->ident.node.is_new) {
return t;
}
t->outer = current_type;
t->funcs = NULL;
t->funcs_list = NULL;
t->inner_types = NULL;
t->inner_types_list = NULL;
t->next = NULL;
if (current_type) {
*inner_type_nextptr = t;
inner_type_nextptr = &t->next;
} else {
*type_nextptr = t;
type_nextptr = &t->next;
}
return t;
}
void type_start(const char *name, size_t len)
{
struct Type *t;
t = map_named_type(name, len);
if (t->ident.node.is_defined) {
error("Duplicate type name");
}
t->ident.node.is_defined = 1;
if (current_type) {
innertype_func_nextptr = &t->funcs_list;
} else {
type_func_nextptr = &t->funcs_list;
inner_type_nextptr = &t->inner_types_list;
}
current_type = t;
}
void type_end(void)
{
current_type = current_type->outer;
}
struct Func *map_named_func(const char *name, size_t len)
{
struct Func *f;
struct TreeNode **root;
/* XXX similar problem as for types */
root = (current_type ?
¤t_type->funcs : &module->funcs);
f = (struct Func *)tree_insert_str(root,
name, len, NULL, sizeof(struct Func));
f->class_ = current_type;
f->params = NULL;
f->returns = NULL;
f->vardecls = NULL;
f->vars = NULL;
f->code = NULL;
f->section_first = NULL;
f->section_by_name = NULL;
f->is_noreturn = 0;
f->num_params = 0;
f->num_returns = 0;
f->next = NULL;
if (current_type && current_type->outer) {
*innertype_func_nextptr = f;
innertype_func_nextptr = &f->next;
} else if (current_type) {
*type_func_nextptr = f;
type_func_nextptr = &f->next;
} else {
*func_nextptr = f;
func_nextptr = &f->next;
}
return f;
}
void func_start(const char *name, size_t len)
{
struct Func *f;
f = map_named_func(name, len);
if (f->ident.node.is_defined) {
error("Duplicate function name");
}
f->ident.node.is_defined = 1;
current_func = f;
}
void func_end(void)
{
current_func = NULL;
}
|