resolver.h 5.6 KiB raw
1
#ifndef RESOLVER_H
2
#define RESOLVER_H
3
4
#include "ast.h"
5
#include "limits.h"
6
#include "module.h"
7
#include "parser.h"
8
#include "riscv.h"
9
#include "symtab.h"
10
#include "types.h"
11
12
/* Built-in slice/array fields */
13
#define LEN_FIELD     "len"
14
#define LEN_FIELD_LEN 3
15
#define PTR_FIELD     "ptr"
16
#define PTR_FIELD_LEN 3
17
18
typedef struct type_t {
19
    typeclass_t cls;
20
21
    const char *name;    /* Type name */
22
    u16         namelen; /* Type name length */
23
24
    union {
25
        struct {
26
            union_decl_t *decl; /* AST node for the union. */
27
            symbol_t    **variants;
28
            u8            nvariants;
29
            struct type_t
30
                *base;        /* Underlying scalar type for fieldless unions */
31
            i32  variantsize; /* Largest payload size (bytes) */
32
            bool has_payload; /* Whether any variant carries data */
33
        } uni;
34
        struct {
35
            struct type_t *err;     /* Error set */
36
            struct type_t *payload; /* Success payload type */
37
        } res;
38
        struct {
39
            symbol_t **fields;     /* Fields of the record */
40
            u8         nfields;    /* Number of fields */
41
            u32        packedsize; /* Size if packed */
42
            bool       anonymous;  /* Anonymous record */
43
            bool       tuple;      /* Tuple-style record */
44
        } srt;
45
        struct {
46
            struct type_t *target; /* Target type. */
47
            bool           mut;    /* Mutable pointer. */
48
        } ptr;
49
        struct {
50
            struct type_t  *ret;    /* Return type */
51
            struct type_t **params; /* Parameter types */
52
            struct type_t **throws;
53
            u8              nparams;
54
            u8              nthrows;
55
        } fun;
56
        struct {
57
            struct type_t *elem;   /* Type of array elements */
58
            u32            length; /* Length for arrays (fixed size) */
59
        } ary;
60
        struct {
61
            struct type_t *elem; /* Type of slice elements */
62
            struct type_t *base; /* Base array type */
63
            bool           mut;  /* Mutable slice pointer. */
64
        } slc;
65
        struct {
66
            struct type_t *elem; /* Type of the optional value */
67
        } opt;
68
    } info;
69
70
    struct type_t *ptr;       /* Pointer type, eg. `*T` for `T`. */
71
    struct type_t *ptr_mut;   /* Mutable pointer type, eg. `*mut T`. */
72
    struct type_t *slice;     /* Slice type, eg. *[T] for [T]. */
73
    struct type_t *slice_mut; /* Mutable slice type, eg. *mut [T]. */
74
75
    i32 size;  /* Calculated size in bytes. */
76
    i32 align; /* Alignment requirements. */
77
} type_t;
78
79
/* Global type context. */
80
typedef struct {
81
    /* Built-in types.
82
     * These point into the `objects` array. */
83
    type_t *type_i8;
84
    type_t *type_u8;
85
    type_t *type_i16;
86
    type_t *type_u16;
87
    type_t *type_i32;
88
    type_t *type_u32;
89
    type_t *type_bool;
90
    type_t *type_char;
91
    type_t *type_str;
92
93
    /* For statements, which have no type. */
94
    type_t *type_void;
95
    /* Opaque type that can only be used behind pointers. */
96
    type_t *type_opaque;
97
    /* For expressions that never produce a value. */
98
    type_t *type_never;
99
100
    /* Type storage across all modules. */
101
    type_t objects[MAX_TYPES];
102
    u16    nobjects;
103
104
    /* Pools for pointer arrays inside type_t (variants, fields, params,
105
     * throws). Each type_t stores a pointer into one of these pools. */
106
    symbol_t      *sympool[MAX_SYMPTR_POOL];
107
    u16            nsympool;
108
    struct type_t *typepool[MAX_TYPEPTR_POOL];
109
    u16            ntypepool;
110
} types_t;
111
112
typedef enum {
113
    TC_CTX_NORMAL  = 0,
114
    TC_CTX_PATTERN = 1,
115
    TC_CTX_TRY     = 2,
116
} resolve_ctx_t;
117
118
/* Type checker state. */
119
typedef struct {
120
    scope_t          *global;
121
    types_t           types;
122
    symbol_t         *fn;     /* Track the current function. */
123
    scope_t          *scope;  /* Track the current scope. */
124
    module_manager_t *mm;     /* Reference to module manager for imports */
125
    module_t         *module; /* Currently being resolved module */
126
    u32               flags;
127
    u16               recordid; /* Next anonymous record ID */
128
    resolve_ctx_t     ctx;      /* Allow unbound identifiers in patterns */
129
} resolve_t;
130
131
/* Allocate `n` symbol_t* slots from the type pool. */
132
symbol_t **types_alloc_sympool(types_t *t, u8 n);
133
/* Allocate `n` type_t* slots from the type pool. */
134
type_t **types_alloc_typepool(types_t *t, u8 n);
135
136
/* Dereference a type. */
137
type_t *deref_type(type_t *ref);
138
139
/* Initialize type checker. */
140
void resolve_init(resolve_t *t, module_manager_t *mm);
141
/* Typecheck a complete AST. */
142
bool resolve_run(resolve_t *t, module_t *root);
143
144
/* Check if a type is numeric, eg. integer or float. */
145
bool type_is_numeric(typeclass_t t);
146
/* Check if a type is compound, ie. is made of multiple sub-types. */
147
bool type_is_compound(type_t *t);
148
/* Check if a type is an address, eg. a pointer or slice. */
149
bool type_is_address(typeclass_t t);
150
/* Check if a type is an integer */
151
bool type_is_int(typeclass_t t);
152
/* Check if a type is an unsigned integer */
153
bool type_is_unsigned(typeclass_t t);
154
/* Check if a type is primitive, ie. not compound. */
155
bool type_is_primitive(type_t *t);
156
/* Check if a type is passed by reference automatically. */
157
bool type_is_passed_by_ref(type_t *t);
158
/* Check if a type is a tagged value */
159
bool type_is_tagged_value(type_t *ty);
160
/* Check if a type is a union with a payload value */
161
bool type_is_union_with_payload(type_t *ty);
162
/* Check if a type is packed, ie. it has no padding */
163
bool type_is_packed(type_t *t);
164
/* Check if type `a` can be coerced to type `b`. This handles cases like
165
 * *mut [T] -> *[T] where the types are structurally compatible. */
166
bool type_coercible(type_t *a, type_t *b);
167
168
#endif