ast.c 5.0 KiB raw
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
#include "ast.h"
6
#include "module.h"
7
#include "parser.h"
8
#include "resolver.h"
9
#include "symtab.h"
10
11
/* String representations of value types. */
12
const char *type_names[] = {
13
    [TYPE_VOID] = "void",     [TYPE_I8] = "i8",        [TYPE_I16] = "i16",
14
    [TYPE_I32] = "i32",       [TYPE_U8] = "u8",        [TYPE_U16] = "u16",
15
    [TYPE_U32] = "u32",       [TYPE_F32] = "f32",      [TYPE_BOOL] = "bool",
16
    [TYPE_FN] = "fn",         [TYPE_UNION] = "union",  [TYPE_RESULT] = "result",
17
    [TYPE_RECORD] = "record", [TYPE_ARRAY] = "array",  [TYPE_SLICE] = "slice",
18
    [TYPE_PTR] = "pointer",   [TYPE_OPT] = "optional", [TYPE_NEVER] = "never",
19
    [TYPE_OPAQUE] = "opaque"
20
};
21
22
/* String representations of node classes. */
23
const char *node_names[] = {
24
    [NODE_TYPE]     = "TYPE",
25
    [NODE_NUMBER]   = "NUMBER",
26
    [NODE_BOOL]     = "BOOL",
27
    [NODE_CHAR]     = "CHAR",
28
    [NODE_STRING]   = "STRING",
29
    [NODE_UNDEF]    = "UNDEFINED",
30
    [NODE_NIL]      = "NIL",
31
    [NODE_IDENT]    = "IDENT",
32
    [NODE_SUPER]    = "SUPER",
33
    [NODE_BINOP]    = "BINOP",
34
    [NODE_UNOP]     = "UNOP",
35
    [NODE_BLOCK]    = "BLOCK",
36
    [NODE_CALL]     = "CALL",
37
    [NODE_BUILTIN]  = "BUILTIN",
38
    [NODE_CALL_ARG] = "ARG",
39
    [NODE_ASSIGN]   = "ASSIGN",
40
    [NODE_PTR]      = "PTR",
41
    [NODE_MOD]      = "MOD",
42
    [NODE_MOD_BODY] = "MODULE",
43
44
    [NODE_PANIC]            = "PANIC",
45
    [NODE_RETURN]           = "RETURN",
46
    [NODE_THROW]            = "THROW",
47
    [NODE_WHILE]            = "WHILE",
48
    [NODE_WHILE_LET]        = "WHILE_LET",
49
    [NODE_FOR]              = "FOR",
50
    [NODE_LOOP]             = "LOOP",
51
    [NODE_TRY]              = "TRY",
52
    [NODE_IF]               = "IF",
53
    [NODE_IF_LET]           = "IF_LET",
54
    [NODE_IF_CASE]          = "IF_CASE",
55
    [NODE_GUARD_CASE]       = "GUARD_CASE",
56
    [NODE_GUARD_LET]        = "GUARD_LET",
57
    [NODE_MATCH]            = "SWITCH",
58
    [NODE_MATCH_CASE]       = "SWITCH_CASE",
59
    [NODE_CATCH]            = "CATCH",
60
    [NODE_FN]               = "FUNCTION",
61
    [NODE_VAR]              = "VAR",
62
    [NODE_CONST]            = "CONST",
63
    [NODE_STATIC]           = "STATIC",
64
    [NODE_REF]              = "REF",
65
    [NODE_PARAM]            = "PARAM",
66
    [NODE_ATTRIBUTE]        = "ATTRIBUTE",
67
    [NODE_BREAK]            = "BREAK",
68
    [NODE_EXPR_STMT]        = "EXPR_STMT",
69
    [NODE_RECORD]           = "RECORD",
70
    [NODE_RECORD_FIELD]     = "RECORD_FIELD",
71
    [NODE_RECORD_TYPE]      = "RECORD_TYPE",
72
    [NODE_UNION]            = "UNION",
73
    [NODE_UNION_VARIANT]    = "UNION_VARIANT",
74
    [NODE_RECORD_LIT]       = "RECORD_LIT",
75
    [NODE_RECORD_LIT_FIELD] = "RECORD_LIT_FIELD",
76
    [NODE_ARRAY_LIT]        = "ARRAY_LIT",
77
    [NODE_ARRAY_INDEX]      = "ARRAY_INDEX",
78
    [NODE_ACCESS]           = "ACCESS",
79
    [NODE_SCOPE]            = "SCOPE",
80
    [NODE_AS]               = "AS",
81
    [NODE_RANGE]            = "RANGE",
82
    [NODE_USE]              = "USE",
83
    [NODE_PLACEHOLDER]      = "PLACEHOLDER",
84
};
85
86
/* Check if the node is a binary comparison operation. */
87
bool node_is_comp(node_t *n) {
88
    if (n->cls != NODE_BINOP)
89
        return false;
90
91
    binop_t op = n->val.binop.op;
92
93
    return op == OP_EQ || op == OP_NE || op == OP_LT || op == OP_GT ||
94
           op == OP_LE || op == OP_GE || op == OP_AND || op == OP_OR;
95
}
96
97
/* Check if the node is a literal value. */
98
bool node_is_literal(node_t *n) {
99
    switch (n->cls) {
100
    case NODE_ARRAY_LIT:
101
    case NODE_ARRAY_REPEAT_LIT:
102
    case NODE_RECORD_LIT:
103
    case NODE_UNION_VARIANT:
104
    case NODE_NUMBER:
105
    case NODE_BOOL:
106
    case NODE_STRING:
107
    case NODE_CHAR:
108
    case NODE_NIL:
109
    case NODE_UNDEF:
110
        return true;
111
    default:
112
        return false;
113
    }
114
}
115
116
/* Check if the binary operator is a logical one. */
117
bool op_is_logical(binop_t op) {
118
    return op == OP_AND || op == OP_OR;
119
}
120
121
/* Access node pointers from a span. */
122
node_t **nodespan_ptrs(parser_t *p, nodespan_t span) {
123
    return &p->ptrs[span.idx];
124
}
125
126
/* Allocate a new span from the parser's pointer pool. */
127
nodespan_t nodespan_alloc(parser_t *p, u16 cap) {
128
    nodespan_t span  = { .idx = (u32)p->nptrs, .len = 0, .cap = cap };
129
    p->nptrs        += cap;
130
    return span;
131
}
132
133
/* Append a node to a span. Returns false on overflow. */
134
bool nodespan_push(parser_t *p, nodespan_t *span, node_t *node) {
135
    if (span->len >= span->cap) {
136
        u16 newcap = span->cap == 0 ? 8 : span->cap * 2;
137
        if (p->nptrs + newcap > MAX_NODEPTR_POOL) {
138
            return false;
139
        }
140
        u32 newidx = (u32)p->nptrs;
141
        for (u16 i = 0; i < span->len; i++) {
142
            p->ptrs[newidx + i] = p->ptrs[span->idx + i];
143
        }
144
        span->idx  = newidx;
145
        span->cap  = newcap;
146
        p->nptrs  += newcap;
147
    }
148
    p->ptrs[span->idx + span->len++] = node;
149
    return true;
150
}
151
152
/* Add a statement to a block node using module's parser. */
153
void node_block_add_stmt(module_t *mod, node_t *block, node_t *stmt) {
154
    nodespan_push(&mod->parser, &block->val.block.stmts, stmt);
155
}
156
157
void node_fn_add_param(parser_t *p, node_t *fn, node_t *param) {
158
    nodespan_push(p, &fn->val.fn_decl.params, param);
159
}