-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathscope.c
135 lines (110 loc) · 3.11 KB
/
scope.c
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
#include "compiler.h"
#include "helpers/vector.h"
#include <memory.h>
#include <stdlib.h>
#include <assert.h>
struct scope* scope_alloc()
{
struct scope* scope = calloc(1, sizeof(struct scope));
scope->entities = vector_create(sizeof(void*));
vector_set_peek_pointer_end(scope->entities);
vector_set_flag(scope->entities, VECTOR_FLAG_PEEK_DECREMENT);
return scope;
}
void scope_dealloc(struct scope* scope)
{
// Do nothing for now.
}
struct scope* scope_create_root(struct compile_process* process)
{
assert(!process->scope.root);
assert(!process->scope.current);
struct scope* root_scope = scope_alloc();
process->scope.root = root_scope;
process->scope.current = root_scope;
return root_scope;
}
void scope_free_root(struct compile_process* process)
{
scope_dealloc(process->scope.root);
process->scope.root = NULL;
process->scope.current = NULL;
}
struct scope* scope_new(struct compile_process* process, int flags)
{
assert(process->scope.root);
assert(process->scope.current);
struct scope* new_scope = scope_alloc();
new_scope->flags = flags;
new_scope->parent = process->scope.current;
process->scope.current = new_scope;
return new_scope;
}
void scope_iteration_start(struct scope* scope)
{
vector_set_peek_pointer(scope->entities, 0);
if (scope->entities->flags & VECTOR_FLAG_PEEK_DECREMENT)
{
vector_set_peek_pointer_end(scope->entities);
}
}
void scope_iteration_end(struct scope* scope)
{
}
void* scope_iterate_back(struct scope* scope)
{
if (vector_count(scope->entities) == 0)
return NULL;
return vector_peek_ptr(scope->entities);
}
void* scope_last_entity_at_scope(struct scope* scope)
{
if (vector_count(scope->entities) == 0)
return NULL;
return vector_back_ptr(scope->entities);
}
void* scope_last_entity_from_scope_stop_at(struct scope* scope, struct scope* stop_scope)
{
if (scope == stop_scope)
{
return NULL;
}
void* last = scope_last_entity_at_scope(scope);
if (last)
{
return last;
}
struct scope* parent = scope->parent;
if (parent)
{
return scope_last_entity_from_scope_stop_at(parent, stop_scope);
}
return NULL;
}
void* scope_last_entity_stop_at(struct compile_process* process, struct scope* stop_scope)
{
return scope_last_entity_from_scope_stop_at(process->scope.current, stop_scope);
}
void* scope_last_entity(struct compile_process* process)
{
return scope_last_entity_stop_at(process, NULL);
}
void scope_push(struct compile_process* process, void* ptr, size_t elem_size)
{
vector_push(process->scope.current->entities, &ptr);
process->scope.current->size += elem_size;
}
void scope_finish(struct compile_process* process)
{
struct scope* new_current_scope = process->scope.current->parent;
scope_dealloc(process->scope.current);
process->scope.current = new_current_scope;
if (process->scope.root && !process->scope.current)
{
process->scope.root = NULL;
}
}
struct scope* scope_current(struct compile_process* process)
{
return process->scope.current;
}