ast.h 15.1 KiB raw
1
#ifndef AST_H
2
#define AST_H
3
4
#include <stdio.h>
5
6
#include "limits.h"
7
#include "symtab.h"
8
#include "types.h"
9
10
/* String representations of value types. */
11
extern const char *type_names[];
12
/* String representations of node classes. */
13
extern const char *node_names[];
14
15
/* Span into parser's pointer pool. Used instead of embedded arrays
16
 * to keep node_t small. Access via parser_get_ptrs(). */
17
typedef struct {
18
    u32 idx; /* Starting index into parser_t.ptrs */
19
    u16 len; /* Number of elements */
20
    u16 cap; /* Capacity (for growable spans) */
21
} nodespan_t;
22
23
/* Variable declaration */
24
typedef struct {
25
    struct node_t *ident;
26
    struct node_t *type;
27
    struct node_t *value;
28
    struct node_t *align;
29
    bool mutable;
30
} var_decl_t;
31
32
/* Constant declaration */
33
typedef struct {
34
    struct node_t *ident;
35
    struct node_t *type;
36
    struct node_t *value;
37
} const_decl_t;
38
39
typedef struct {
40
    struct node_t *ident;
41
    struct node_t *type;
42
    struct node_t *value;
43
} static_decl_t;
44
45
/* Record type declaration. */
46
typedef struct {
47
    struct node_t *name;    /* Name of the record */
48
    nodespan_t     fields;  /* Fields of the record */
49
    struct node_t *attribs; /* Attributes (e.g. pub) */
50
    bool           tuple;   /* Unlabeled fields */
51
} record_decl_t;
52
53
typedef struct {
54
    nodespan_t fields; /* Fields of the record */
55
} record_type_t;
56
57
typedef struct {
58
    struct node_t *name;  /* Field name */
59
    struct node_t *value; /* Field value expression */
60
} record_lit_field_t;
61
62
/* Union variant definition. */
63
typedef struct {
64
    struct node_t *name;       /* Name of the variant */
65
    struct node_t *type;       /* Optional payload type */
66
    i32            value;      /* Value or tag for the variant */
67
    struct node_t *value_expr; /* Literal expression when explicitly assigned */
68
} union_variant_t;
69
70
/* Union type declaration. */
71
typedef struct {
72
    struct node_t *name;     /* Name of the union */
73
    nodespan_t     variants; /* Variants of the union */
74
    struct node_t *attribs;  /* Attributes (e.g. pub) */
75
} union_decl_t;
76
77
/* Function definition. */
78
typedef struct {
79
    struct node_t *ident;
80
    nodespan_t     params;
81
    struct node_t *return_type;
82
    nodespan_t     throws;
83
    struct node_t *body; /* Will be NULL for `extern` functions */
84
    struct node_t *attribs;
85
} fn_decl_t;
86
87
/* Node type. */
88
typedef enum {
89
    /* Literals. */
90
    NODE_NUMBER,
91
    NODE_CHAR,
92
    NODE_STRING,
93
    NODE_BOOL,
94
    NODE_NIL,              /* Nil literal */
95
    NODE_UNDEF,            /* Undefined literal */
96
    NODE_RECORD_LIT,       /* Record literal (e.g. Foo { x: 1, y: 2 }) */
97
    NODE_RECORD_LIT_FIELD, /* Record literal field */
98
    NODE_ARRAY_LIT,        /* Array literal (e.g. [1, 2, 3]) */
99
    NODE_ARRAY_REPEAT_LIT, /* Array repeat literal (e.g. [0; 24]) */
100
    NODE_ARRAY_INDEX,      /* Array indexing (e.g. arr[0]) */
101
    NODE_RANGE,            /* Range expression (e.g. 0..5 or ..) */
102
103
    /* Expressions. */
104
    NODE_IDENT,
105
    NODE_SUPER, /* `super` path segment */
106
    NODE_BINOP,
107
    NODE_UNOP, /* Unary operation (e.g., not x) */
108
    NODE_BLOCK,
109
    NODE_CALL,
110
    NODE_BUILTIN,
111
    NODE_CALL_ARG, /* Function call argument, optionally labeled (e.g. x: 1) */
112
    NODE_ACCESS,   /* (eg. foo.bar) */
113
    NODE_SCOPE,    /* (eg. foo::bar) */
114
    NODE_REF,      /* (eg., &foo) */
115
    NODE_AS,       /* (eg. x as i32) */
116
117
    /* Statements. */
118
    NODE_MOD,      /* Module declaration: mod foo; */
119
    NODE_MOD_BODY, /* Module body content */
120
    NODE_RETURN,
121
    NODE_THROW,
122
    NODE_WHILE,
123
    NODE_WHILE_LET, /* While let statement */
124
    NODE_LOOP,
125
    NODE_TRY,
126
    NODE_IF,
127
    NODE_IF_LET,     /* If let statement (eg. if let x in (opt) { ... }) */
128
    NODE_IF_CASE,    /* If case statement (eg. if case Foo::Bar(x) = expr) */
129
    NODE_GUARD_CASE, /* let case else statement */
130
    NODE_GUARD_LET,  /* let else statement */
131
    NODE_MATCH,      /* Switch statement (eg. switch (x) { ... }) */
132
    NODE_MATCH_CASE, /* Switch case (eg. case 1 => { ... }) */
133
    NODE_CATCH,
134
    NODE_FN,
135
    NODE_VAR, /* Variable declaration */
136
    NODE_CONST,
137
    NODE_STATIC,
138
    NODE_PARAM, /* Function parameter */
139
    NODE_BREAK,
140
    NODE_FOR,
141
    NODE_ASSIGN,
142
    NODE_EXPR_STMT,
143
    NODE_USE,   /* Module use declaration (e.g. use std.net) */
144
    NODE_PANIC, /* Panic statement */
145
146
    /* Type declarations. */
147
    NODE_TYPE,
148
    NODE_PTR, /* Pointer type */
149
    NODE_ALIGN,
150
    NODE_ATTRIBUTE,
151
    NODE_RECORD,       /* Record type declaration. */
152
    NODE_RECORD_FIELD, /* Field in record declaration */
153
    NODE_RECORD_TYPE,  /* Anonymous record type */
154
    NODE_UNION,
155
    NODE_UNION_VARIANT,
156
    NODE_PLACEHOLDER, /* Placeholder `_` for unused bindings */
157
} nodeclass_t;
158
159
/* Compiler built-ins */
160
typedef enum {
161
    BUILTIN_SIZE_OF,
162
    BUILTIN_ALIGN_OF,
163
    BUILTIN_SLICE_OF
164
} builtin_kind_t;
165
166
/* Binary operators. */
167
typedef enum {
168
    OP_ADD,
169
    OP_SUB,
170
    OP_MUL,
171
    OP_DIV,
172
    OP_MOD,
173
    OP_EQ,
174
    OP_NE,
175
    OP_LT,
176
    OP_GT,
177
    OP_LE,
178
    OP_GE,
179
    OP_AND,
180
    OP_OR,
181
    OP_BAND, /* Bitwise AND (&) */
182
    OP_BOR,  /* Bitwise OR (|) */
183
    OP_XOR,  /* Bitwise XOR (^) */
184
    OP_SHL,  /* Shift left (<<) */
185
    OP_SHR,  /* Shift right (>>) */
186
} binop_t;
187
188
/* Unary operators. */
189
typedef enum {
190
    OP_NOT,
191
    OP_NEG, /* Numeric negation */
192
    OP_DEREF,
193
    OP_BNOT, /* Bitwise NOT (~) */
194
} unop_t;
195
196
/* A node in the abstract syntax tree. */
197
typedef struct node_t {
198
    /* Fields set by parser. */
199
    nodeclass_t cls;    /* Node class. */
200
    u32         offset; /* Byte offset into source code for this node. */
201
    u32         length; /* Length of source code for this node. */
202
    const char *file;   /* Source file this node was parsed from. */
203
204
    /* Fields set by resolver. */
205
    symbol_t      *sym;  /* Symbol table entry, if any. */
206
    struct type_t *type; /* Type context, if any. */
207
208
    /* Node value, set during parsing. */
209
    union {
210
        /* Boolean literal. */
211
        bool bool_lit;
212
        /* Character literal. */
213
        char char_lit;
214
215
        struct {
216
            const char *data;
217
            u16         length;
218
        } string_lit;
219
220
        /* Expression statement. */
221
        struct node_t *expr_stmt;
222
223
        /* Attribute node. */
224
        attrib_t attrib;
225
226
        /* Type node. */
227
        struct {
228
            /* The type represented by this node. If a complex type,
229
             * additional information is found in the `info` union. */
230
            typeclass_t    tclass;
231
            struct node_t *elem_type;
232
233
            union {
234
                struct {
235
                    struct node_t *length;
236
                } array;
237
238
                struct {
239
                    bool mut;
240
                } ptr;
241
242
                struct {
243
                    bool mut;
244
                } slice;
245
246
                struct {
247
                    nodespan_t     params; /* Parameter types */
248
                    struct node_t *ret;    /* Return type */
249
                    nodespan_t     throws;
250
                } fn;
251
            } info;
252
        } type;
253
254
        /* Reference node. */
255
        struct {
256
            struct node_t *target; /* Target of the reference. */
257
            bool           mut;    /* If this is a mutable reference. */
258
        } ref;
259
260
        /* Align expression */
261
        struct node_t *align;
262
263
        /* Expression nodes. */
264
        struct {
265
            const char *text;     /* Original text of the number literal */
266
            u16         text_len; /* Length of the original text */
267
            imm_t       value;    /* Parsed value based on type context */
268
        } number;
269
270
        struct {
271
            const char *name;
272
            u16         length;
273
        } ident;
274
275
        struct {
276
            binop_t        op;
277
            struct node_t *left;
278
            struct node_t *right;
279
        } binop;
280
281
        struct {
282
            unop_t         op;
283
            struct node_t *expr;
284
        } unop;
285
286
        struct {
287
            struct node_t *expr; /* Expression to cast */
288
            struct node_t *type; /* Target type */
289
        } as_expr;
290
291
        struct {
292
            nodespan_t      stmts;
293
            struct scope_t *scope; /* Scope for this block */
294
        } block;
295
296
        struct {
297
            struct node_t *callee;
298
            nodespan_t     args;
299
        } call;
300
301
        struct {
302
            builtin_kind_t kind;
303
            nodespan_t     args; /* Arguments to builtin */
304
        } builtin;
305
306
        struct {
307
            struct node_t *label; /* Optional label, or `NULL`. */
308
            struct node_t *expr;  /* Argument expression. */
309
        } call_arg;
310
311
        struct {
312
            struct node_t *lval;
313
            struct node_t *rval;
314
        } assign;
315
316
        struct {
317
            struct node_t *value;
318
        } return_stmt;
319
320
        struct {
321
            struct node_t *expr;
322
        } throw_stmt;
323
324
        struct {
325
            struct node_t *message; /* Optional message expression */
326
        } panic_stmt;
327
328
        struct {
329
            struct node_t *cond;
330
            struct node_t *body;
331
            struct node_t *rbranch; /* Optional else clause */
332
        } while_stmt;
333
334
        struct {
335
            struct node_t  *var;     /* Variable to bind */
336
            struct node_t  *expr;    /* Optional expression to unwrap */
337
            struct node_t  *guard;   /* Optional guard condition */
338
            struct node_t  *body;    /* Loop body */
339
            struct node_t  *rbranch; /* Optional else clause */
340
            struct scope_t *scope;   /* Holds the bound variable */
341
        } while_let_stmt;
342
343
        struct {
344
            struct node_t  *var;
345
            struct node_t  *idx; /* Optional index variable */
346
            struct node_t  *iter;
347
            struct node_t  *body;
348
            struct node_t  *rbranch; /* Optional else clause */
349
            struct scope_t *scope;   /* Holds the temporary variable. */
350
        } for_stmt;
351
352
        struct {
353
            struct node_t *body;
354
        } loop_stmt;
355
356
        struct {
357
            struct node_t *expr;       /* Expression guarded by try */
358
            struct node_t *catch_expr; /* Fallback expression for catch */
359
            nodespan_t     handlers;
360
            bool           panic; /* Emit ebreak on error when true */
361
            bool optional;        /* Return optional instead of propagating */
362
        } try_expr;
363
364
        struct {
365
            struct node_t *cond;
366
            struct node_t *lbranch;
367
            struct node_t *rbranch;
368
        } if_stmt;
369
370
        struct {
371
            struct node_t  *var;     /* Variable to bind */
372
            struct node_t  *expr;    /* Optional expression to unwrap */
373
            struct node_t  *guard;   /* Optional guard */
374
            struct node_t  *lbranch; /* Then branch */
375
            struct node_t  *rbranch; /* Else branch (optional) */
376
            struct scope_t *scope;   /* Holds the bound variable */
377
        } if_let_stmt;
378
379
        struct {
380
            struct node_t *pattern; /* Pattern to match */
381
            struct node_t *expr;    /* Expression being tested */
382
            struct node_t *guard;   /* Optional guard */
383
            struct node_t *lbranch; /* Then branch */
384
            struct node_t *rbranch; /* Else branch (optional) */
385
        } if_case_stmt;
386
387
        struct {
388
            struct node_t *pattern; /* Pattern to match */
389
            struct node_t *expr;    /* Expression being tested */
390
            struct node_t *guard;   /* Optional guard */
391
            struct node_t *rbranch; /* Else branch */
392
        } guard_case_stmt;
393
394
        struct {
395
            struct node_t *var;     /* Bound variable */
396
            struct node_t *expr;    /* Optional expression to unwrap */
397
            struct node_t *rbranch; /* Else branch */
398
        } guard_let_stmt;
399
400
        struct {
401
            struct node_t *expr;
402
            nodespan_t     cases; /* Switch cases */
403
        } match_stmt;
404
405
        struct {
406
            nodespan_t     patterns;
407
            struct node_t *body;     /* Case body */
408
            struct node_t *guard;    /* Optional guard condition */
409
            struct node_t *variable; /* Bound variable */
410
        } match_case;
411
412
        struct {
413
            struct node_t  *binding; /* Optional bound identifier */
414
            struct node_t  *body;    /* Catch handler body */
415
            struct scope_t *scope;   /* Scope for the bound variable */
416
        } catch_clause;
417
418
        var_decl_t    var;
419
        const_decl_t  constant;
420
        static_decl_t static_decl;
421
422
        struct {
423
            struct node_t *ident;
424
            struct node_t *type;
425
        } param;
426
427
        union_decl_t    union_decl;
428
        union_variant_t union_variant;
429
430
        struct {
431
            struct node_t *type;   /* Type identifier */
432
            nodespan_t     fields; /* Field initializers */
433
            bool           etc;    /* Pattern discards remaining fields */
434
        } record_lit;
435
436
        /* Field initialization in a record literal. */
437
        record_lit_field_t record_lit_field;
438
439
        /* Record declarations. */
440
        record_decl_t record_decl;
441
        /* Anonymous record */
442
        record_type_t record_type;
443
444
        /* Array indexing and record field access, eg. `x.y` or `x[y]`. */
445
        struct {
446
            struct node_t *lval;
447
            struct node_t *rval;
448
        } access;
449
450
        /* Range expression, e.g. `0..5` or `..` */
451
        struct {
452
            struct node_t *start; /* Start expression (NULL if omitted) */
453
            struct node_t *end;   /* End expression (NULL if omitted) */
454
        } range;
455
456
        /* Array literal, e.g. `[1, 2, 3]` */
457
        struct {
458
            nodespan_t elems;
459
        } array_lit;
460
461
        /* Array repeat literal, e.g. `[0; 24]` */
462
        struct {
463
            struct node_t *value; /* Value to repeat */
464
            struct node_t *count; /* Number of repetitions */
465
        } array_repeat_lit;
466
467
        /* Use declaration, e.g. `use std::net::tcp;` */
468
        struct {
469
            struct node_t *path;     /* Path to the module being used */
470
            struct node_t *attribs;  /* Attributes (e.g. pub) */
471
            bool           wildcard; /* Whether this is a wildcard import */
472
        } use_decl;
473
474
        /* Module declaration, e.g. `mod util;` */
475
        struct {
476
            struct node_t *ident;   /* Name of the module */
477
            struct node_t *attribs; /* Attributes (e.g. pub) */
478
        } mod_decl;
479
480
        fn_decl_t fn_decl;
481
    } val;
482
} node_t;
483
484
/* Forward declaration for parser_t */
485
struct parser_t;
486
487
/* Check if the node is a binary comparison operation. */
488
bool node_is_comp(node_t *n);
489
/* Check if the node is a literal */
490
bool node_is_literal(node_t *n);
491
/* Check if the binary operator is a logical one. */
492
bool op_is_logical(binop_t);
493
/* Add a parameter to a function. */
494
void node_fn_add_param(struct parser_t *p, node_t *fn, node_t *param);
495
496
/* Access node pointers from a span. Requires parser context. */
497
struct parser_t;
498
node_t **nodespan_ptrs(struct parser_t *p, nodespan_t span);
499
500
/* Allocate a new span from the parser's pointer pool. */
501
nodespan_t nodespan_alloc(struct parser_t *p, u16 cap);
502
503
/* Append a node to a span, growing if needed. Returns false on overflow. */
504
bool nodespan_push(struct parser_t *p, nodespan_t *span, node_t *node);
505
506
/* Forward declaration for module_t */
507
struct module_t;
508
509
/* Add a statement to a block node using module's parser. */
510
void node_block_add_stmt(struct module_t *mod, node_t *block, node_t *stmt);
511
512
#endif