gen/
.clang-format
570 B
.gitignore
30 B
.gitsigners
112 B
LICENSE
1.1 KiB
Makefile
911 B
README
1.8 KiB
ast.c
5.0 KiB
ast.h
15.1 KiB
desugar.c
23.1 KiB
desugar.h
286 B
gen.c
108.5 KiB
gen.h
4.9 KiB
io.c
1.1 KiB
io.h
444 B
limits.h
1.3 KiB
module.c
10.0 KiB
module.h
2.2 KiB
options.c
1.4 KiB
options.h
472 B
parser.c
68.3 KiB
parser.h
942 B
radiance.c
3.7 KiB
ralloc.c
2.0 KiB
ralloc.h
1.1 KiB
resolver.c
109.7 KiB
resolver.h
5.6 KiB
riscv.c
12.0 KiB
riscv.h
12.0 KiB
scanner.c
10.2 KiB
scanner.h
3.2 KiB
strings.c
2.6 KiB
strings.h
407 B
symtab.c
5.7 KiB
symtab.h
4.6 KiB
types.h
1.0 KiB
util.h
1.5 KiB
resolver.h
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 |