File: expr.h

package info (click to toggle)
harec 0.26.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,480 kB
  • sloc: ansic: 20,054; asm: 335; makefile: 116; lisp: 80; sh: 45
file content (402 lines) | stat: -rw-r--r-- 7,608 bytes parent folder | download
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
#ifndef HAREC_EXPR_H
#define HAREC_EXPR_H
#include <stdint.h>
#include "lex.h"
#include "types.h"

struct scope;
struct scope_object;

enum expr_type {
	EXPR_ACCESS,
	EXPR_ALLOC,
	EXPR_APPEND,
	EXPR_ASSERT,
	EXPR_ASSIGN,
	EXPR_BINARITHM,
	EXPR_BINDING,
	EXPR_BREAK,
	EXPR_CALL,
	EXPR_CAST,
	EXPR_COMPOUND,
	EXPR_CONTINUE,
	EXPR_DEFER,
	EXPR_DEFINE,
	EXPR_DELETE,
	EXPR_FOR,
	EXPR_FREE,
	EXPR_IF,
	EXPR_INSERT,
	EXPR_LEN,
	EXPR_MEASURE = EXPR_LEN, // for use in AST
	EXPR_LITERAL,
	EXPR_MATCH,
	EXPR_PROPAGATE,
	EXPR_RETURN,
	EXPR_SLICE,
	EXPR_STRUCT,
	EXPR_SWITCH,
	EXPR_TUPLE,
	EXPR_UNARITHM,
	EXPR_UNDEFINED,
	EXPR_VAARG,
	EXPR_VAEND,
	EXPR_VASTART,
	EXPR_YIELD,
};

struct expressions {
	struct expression *expr;
	struct expressions *next;
};

enum access_type {
	ACCESS_IDENTIFIER,
	ACCESS_INDEX,
	ACCESS_FIELD,
	ACCESS_TUPLE,
};

struct expression_access {
	enum access_type type;
	union {
		struct scope_object *object;
		struct {
			struct expression *array;
			struct expression *index;
			bool bounds_checked;
		};
		struct {
			struct expression *_struct;
			const struct struct_field *field;
		};
		struct {
			struct expression *tuple;
			const struct type_tuple *tvalue;
			size_t tindex;
		};
	};
};

enum alloc_kind {
	ALLOC_OBJECT,	// alloc(42)
	ALLOC_CAP,	// alloc([], 42)
	ALLOC_LEN,	// alloc([0...], 42)
	ALLOC_COPY,	// alloc(x...);
};

struct expression_alloc {
	enum alloc_kind kind;
	const struct type *allocation_result;
	struct expression *init;
	struct expression *cap;
};

struct expression_append {
	struct expression *object;
	struct expression *value;
	struct expression *length;
	bool is_static, is_multi;
};

enum fixed_aborts {
	ABORT_OOB = 0,
	ABORT_TYPE_ASSERTION = 1,
	ABORT_UNREACHABLE = 2,
	ABORT_CAP_TOO_SMALL = 3,
	ABORT_ANON_ASSERTION_FAILED = 4,
	ABORT_PROPAGATE_ERROR_OCCURRED = 5,
};

struct expression_assert {
	struct expression *cond;
	struct expression *message;
	enum fixed_aborts fixed_reason;
};

enum binarithm_operator {
	BIN_BAND,	// &
	BIN_BOR,	// |
	BIN_DIV,	// /
	BIN_GREATER,	// >
	BIN_GREATEREQ,	// >=
	BIN_LAND,	// &&
	BIN_LEQUAL,	// ==
	BIN_LESS,	// <
	BIN_LESSEQ,	// <=
	BIN_LOR,	// ||
	BIN_LSHIFT,	// <<
	BIN_LXOR,	// ^^
	BIN_MINUS,	// -
	BIN_MODULO,	// %
	BIN_NEQUAL,	// !=
	BIN_PLUS,	// +
	BIN_RSHIFT,	// >>
	BIN_TIMES,	// *
	BIN_BXOR,	// ^
	BIN_LAST = BIN_BXOR,
};

struct expression_assign {
	enum binarithm_operator op;
	struct expression *object, *value;
};

struct expression_binarithm {
	enum binarithm_operator op;
	struct expression *lvalue, *rvalue;
};

struct binding_unpack {
	const struct scope_object *object;
	size_t offset;
	struct binding_unpack *next;
};

struct expression_binding {
	const struct scope_object *object;
	struct binding_unpack *unpack;
	struct expression *initializer;
	struct expression_binding *next;
};

enum cast_kind {
	C_CAST,
	C_ASSERTION,
	C_TEST,
};

struct expression_cast {
	enum cast_kind kind;
	const struct type *secondary;
	struct expression *value;
	bool lowered;
};

struct call_argument {
	struct expression *value;
	struct call_argument *next;
};

struct expression_call {
	struct expression *lvalue;
	struct call_argument *args;
};

struct expression_compound {
	const char *label;
	struct scope *scope;
	struct expressions exprs;
};

struct array_literal {
	struct expression *value;
	struct array_literal *next;
};

// Invariant: these are sorted by field offset
struct struct_literal {
	const struct struct_field *field;
	struct expression *value;
	struct struct_literal *next;
};

struct tuple_literal {
	const struct type_tuple *field;
	struct expression *value;
	struct tuple_literal *next;
};

struct tagged_literal {
	const struct type *tag;
	struct expression *value;
};

struct expression_literal {
	// If non-null, ival is an offset from this object's address
	const struct scope_object *object;
	union {
		bool bval;
		double fval;
		int64_t ival;
		uint64_t uval;
		uint32_t rune;
		struct {
			size_t len;
			char *value;
		} string;
		struct {
			union {
				// if object is null
				struct array_literal *array;
				// if object is non-null
				size_t offset;
			};
			size_t start;
			size_t len;
			size_t cap;
		} slice;
		struct array_literal *array;
		struct struct_literal *_struct;
		struct tuple_literal *tuple;
		struct tagged_literal tagged;
	};
};

struct expression_control {
	const char *label;
	const struct scope *scope;
	struct expression *value; // Only set for yield and break
};

struct expression_defer {
	struct scope *scope;
	struct expression *deferred;
};

struct expression_delete {
	struct expression *expr;
	bool is_static;
};

enum for_kind {
	FOR_ACCUMULATOR,
	FOR_EACH_VALUE,
	FOR_EACH_POINTER,
	FOR_EACH_ITERATOR,
};

struct expression_for {
	enum for_kind kind;
	const char *label;
	struct scope *scope;
	struct expression *bindings;
	struct expression *cond;
	struct expression *afterthought;
	struct expression *body;
	struct expression *else_branch;
};

struct expression_free {
	struct expression *expr;
};

struct expression_if {
	struct expression *cond;
	struct expression *true_branch, *false_branch;
};

struct match_case {
	const struct scope_object *object;	// NULL if not bound
	const struct type *type;		// NULL if default
	struct expression *value;
	struct match_case *next;
};

struct expression_len {
	struct expression *value;
};

struct expression_match {
	struct expression *value;
	struct match_case *cases;
};

struct expression_return {
	struct expression *value;
};

struct expression_slice {
	struct expression *object;
	struct expression *start, *end;
	bool bounds_checked;
};

struct case_option {
	struct expression *value;
	struct case_option *next;
};

struct switch_case {
	struct case_option *options; // NULL for default case
	struct expression *value;
	struct switch_case *next;
};

struct expression_switch {
	struct expression *value;
	struct switch_case *cases;
};

struct expr_struct_field {
	const struct struct_field *field;
	struct expression *value;
	struct expr_struct_field *next;
};

struct expression_struct {
	struct expr_struct_field *fields;
	bool autofill, undefined;
};

struct expression_tuple {
	struct expression *value;
	struct expression_tuple *next;
};

enum unarithm_operator {
	UN_ADDRESS,	// &
	UN_BNOT,	// ~
	UN_DEREF,	// *
	UN_LNOT,	// !
	UN_MINUS,	// -
};

struct expression_unarithm {
	enum unarithm_operator op;
	struct expression *operand;
};

struct expression_vaarg {
	struct expression *ap;
};

struct expression {
	const struct type *result;
	enum expr_type type;
	struct location loc; // For fixed aborts
	union {
		struct expression_access access;
		struct expression_alloc alloc;
		struct expression_append append; // and insert
		struct expression_assert assert;
		struct expression_assign assign;
		struct expression_binarithm binarithm;
		struct expression_binding binding;
		struct expression_call call;
		struct expression_cast cast;
		struct expression_compound compound;
		struct expression_defer defer;
		struct expression_delete delete;
		struct expression_control control;
		struct expression_for _for;
		struct expression_free free;
		struct expression_if _if;
		struct expression_len len;
		struct expression_literal literal;
		struct expression_match match;
		struct expression_return _return;
		struct expression_switch _switch;
		struct expression_struct _struct;
		struct expression_slice slice;
		struct expression_tuple tuple;
		struct expression_unarithm unarithm;
		struct expression_vaarg vaarg;
		void *user;
	};
};

uint32_t expr_hash(const struct expression *expr);
bool expr_equal(const struct expression *a, const struct expression *b);

#endif