aboutsummaryrefslogtreecommitdiff
path: root/types.h
blob: 40cb448e3cd990e3f8a2eaff9dd9e1eb0a463e3e (plain)
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
#pragma once
#include <libgccjit.h>
#include <printf.h>
#include <stdlib.h>
#include <libgccjit.h>

#include "ast.h"
#include "builtins/array.h"

typedef struct type_s type_t;

typedef struct arg_s {
    const char *name;
    type_t *type;
    ast_t *default_val;
    struct arg_s *next;
} arg_t;

#define ARG_LIST(...) ({\
    arg_t *args[] = {__VA_ARGS__}; \
    for (size_t i = 0; i < sizeof(args)/sizeof(args[0])-1; i++) \
        args[i]->next = args[i+1]; \
    args[0]; })

typedef struct tag_s {
    const char *name;
    int64_t tag_value;
    type_t *type;
    struct tag_s *next;
} tag_t;

typedef struct type_list_s {
    type_t *type;
    struct type_list_s *next;
} type_list_t;

struct type_s {
    enum {
        UnknownType,
        AbortType,
        VoidType,
        MemoryType,
        BoolType,
        IntType,
        NumType,
        TextType,
        ArrayType,
        TableType,
        FunctionType,
        ClosureType,
        PointerType,
        StructType,
        EnumType,
        TypeInfoType,
    } tag;

    union {
        struct {
        } UnknownType, AbortType, VoidType, MemoryType, BoolType;
        struct {
            int64_t bits;
        } IntType;
        struct {
            int64_t bits;
        } NumType;
        struct {
            const char *dsl;
        } TextType;
        struct {
            type_t *item_type;
        } ArrayType;
        struct {
            type_t *key_type, *value_type;
        } TableType;
        struct {
            arg_t *args;
            type_t *ret;
        } FunctionType;
        struct {
            type_t *fn;
        } ClosureType;
        struct {
            type_t *pointed;
            bool is_optional:1, is_stack:1, is_readonly:1;
        } PointerType;
        struct {
            const char *name;
            arg_t *fields;
            bool opaque;
        } StructType;
        struct {
            const char *name;
            tag_t *tags;
            bool opaque;
        } EnumType;
        struct {
            const char *name;
            type_t *type;
        } TypeInfoType;
    } __data;
};

#define Type(typetag, ...) new(type_t, .tag=typetag, .__data.typetag={__VA_ARGS__})
#define INT_TYPE Type(IntType, .bits=64)
#define NUM_TYPE Type(NumType, .bits=64)

int printf_pointer_size(const struct printf_info *info, size_t n, int argtypes[n], int size[n]);
int printf_type(FILE *stream, const struct printf_info *info, const void *const args[]);
CORD type_to_cord(type_t *t);
bool type_eq(type_t *a, type_t *b);
bool type_is_a(type_t *t, type_t *req);
type_t *type_or_type(type_t *a, type_t *b);
type_t *value_type(type_t *a);
typedef enum {NUM_PRECISION_EQUAL, NUM_PRECISION_LESS, NUM_PRECISION_MORE, NUM_PRECISION_INCOMPARABLE} precision_cmp_e;
precision_cmp_e compare_precision(type_t *a, type_t *b);
bool has_heap_memory(type_t *t);
bool has_stack_memory(type_t *t);
bool can_promote(type_t *actual, type_t *needed);
bool can_leave_uninitialized(type_t *t);
bool can_have_cycles(type_t *t);
type_t *replace_type(type_t *t, type_t *target, type_t *replacement);
size_t type_size(type_t *t);
size_t type_align(type_t *t);
type_t *iteration_key_type(type_t *iterable);
type_t *iteration_value_type(type_t *iterable);
type_t *get_field_type(type_t *t, const char *field_name);

// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0