/
pvec.h
175 lines (154 loc) · 3.66 KB
/
pvec.h
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
/*
module : pvec.h
version : 1.10
date : 04/11/24
*/
struct NodeList {
unsigned m : 31, /* capacity */
o : 1; /* ownership */
unsigned n : 30, /* valid items */
r : 2; /* arity */
YYSTYPE *a; /* union */
Operator *b; /* datatype */
};
/* ownership determines whether the vector can have new elements added */
enum owner_t {
NOT_OWNER,
OWNER,
};
#if 0
/* arity tells: saving and restoring stack in a condition is necessary */
enum arity_t {
ARITY_UNKNOWN, /* not yet calculated */
ARITY_NOT_OK,
ARITY_OK,
};
#endif
/* initialize vector header and set the array as not owned by the head */
static inline NodeList *pvec_init(void)
{
NodeList *v = GC_malloc(sizeof(NodeList));
v->m = v->n = 0;
v->a = 0;
v->b = 0;
v->o = NOT_OWNER;
v->r = ARITY_UNKNOWN;
return v;
}
/* pvec_concat concatenates two existing vectors, and returns 1 result */
static inline NodeList *pvec_concat(NodeList *v, NodeList *w)
{
NodeList *r = GC_malloc(sizeof(NodeList));
r->m = r->n = v->n + w->n;
r->a = GC_malloc(r->m * sizeof(YYSTYPE));
r->b = GC_malloc(r->m);
memcpy(r->a, w->a, w->n * sizeof(YYSTYPE));
memcpy(r->b, w->b, w->n);
memcpy(r->a + w->n, v->a, v->n * sizeof(YYSTYPE));
memcpy(r->b + w->n, v->b, v->n);
r->o = OWNER;
r->r = ARITY_UNKNOWN;
return r;
}
/* pvec_add assumes that head has been initialized before it is called */
static inline NodeList *pvec_add(NodeList *v, Node x)
{
void *ptr;
if (v->n == v->m) {
v->m = v->m ? v->m << 1 : 2;
ptr = GC_malloc(v->m * sizeof(YYSTYPE));
if (v->n)
memcpy(ptr, v->a, v->n * sizeof(YYSTYPE));
v->a = ptr;
ptr = GC_malloc(v->m);
if (v->n)
memcpy(ptr, v->b, v->n);
v->b = ptr;
v->o = OWNER;
}
v->a[v->n] = x.u;
v->b[v->n++] = x.op;
return v;
}
static inline int pvec_cnt(NodeList *v)
{
return v ? v->n : 0;
}
static inline int pvec_max(NodeList *v)
{
return v ? v->m : 0;
}
/* pvec_copy assumes that v exists and need not be created array is ok */
static inline void pvec_copy(NodeList *v, NodeList *w)
{
if ((v->n = pvec_cnt(w)) != 0) { /* set new number of items */
if (v->m < v->n) { /* new number exceeds maximum */
v->m = v->n;
v->a = GC_malloc(v->m * sizeof(YYSTYPE));
v->b = GC_malloc(v->m);
v->o = OWNER;
v->r = w->r;
}
memcpy(v->a, w->a, v->n * sizeof(YYSTYPE));
memcpy(v->b, w->b, v->n);
}
}
/* pvec_shallow_copy makes a copy without taking ownership of the array */
static inline void pvec_shallow_copy(NodeList *v, NodeList *w)
{
memcpy(v, w, sizeof(NodeList));
v->o = NOT_OWNER;
}
/* pvec_shallow_copy_take_ownership makes a copy while taking ownership */
static inline void pvec_shallow_copy_take_ownership(NodeList *v, NodeList *w)
{
if (w->o == OWNER) {
memcpy(v, w, sizeof(NodeList));
w->o = NOT_OWNER;
} else
pvec_copy(v, w);
}
static inline Node pvec_nth(NodeList *v, int i)
{
Node node;
node.u = v->a[i];
node.op = v->b[i];
return node;
}
static inline Node pvec_lst(NodeList *v)
{
Node node;
node.u = v->a[v->n - 1];
node.op = v->b[v->n - 1];
return node;
}
static inline NodeList *pvec_upd(NodeList *v, int i, Node x)
{
v->a[i] = x.u;
v->b[i] = x.op;
return v;
}
static inline NodeList *pvec_del(NodeList *v)
{
--v->n;
return v;
}
static inline NodeList *pvec_pop(NodeList *v, Node *node)
{
node->u = v->a[--v->n];
node->op = v->b[v->n];
return v;
}
static inline NodeList *pvec_cut(NodeList *v, int s)
{
v->n = s;
return v;
}
static inline int pvec_getarity(NodeList *v)
{
return v->r;
}
static inline void pvec_setarity(NodeList *v, int s)
{
v->r = s;
}