aboutsummaryrefslogtreecommitdiffstats
path: root/src/nodes.c
blob: 5689d186ed39cd0bf3d096757bd5ecd9c37b5818 (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
#include "nodes.h"

Node *
alloc_node(NodeType type) {
    // TODO: Use a bump allocator?
    // TODO: Free memory!
    Node *node = malloc(sizeof(Node));
    node->type = type;
    node->line = 0;
    node->col = 0;
    node->scope = NULL;
    node->type_class = TYPE_UNK;
    return node;
}

void
print_node(Node *node) {
    if (node == NULL) {
        return;
    }
    switch (node->type) {
        case NODE_NUMBER: {
            if (node->number.negative) {
                printf("-");
            }
            if (node->number.fractional != 0) {
                printf("%zu.%zu", node->number.integral, node->number.fractional);
            } else {
                printf("%zu", node->number.integral);
            }
        } break;
        case NODE_SYMBOL:
        case NODE_TYPE:
        case NODE_STRING: {
            sv_write(&node->string);
        } break;
        case NODE_BOOL: {
            if (node->boolean) {
                printf("true");
            } else {
                printf("false");
            }
        } break;
        case NODE_BUILTIN: {
            printf("({%s}", token_str[node->builtin.type]);
            size_t n_args = array_size(node->builtin.args);
            if (n_args != 0) {
                printf(" ");
            }
            for (size_t i = 0; i < n_args; ++i) {
                print_node(node->builtin.args[i]);
                if (i < n_args - 1) {
                    printf(" ");
                }
            }
            printf(")");
        } break;
        case NODE_DEF: {
            printf("(def ");
            print_node(node->def.symbol);
            printf(":");
            print_node(node->def.type);
            printf(" ");
            print_node(node->def.value);
            printf(")");
        } break;
        case NODE_SET: {
            printf("(set ");
            print_node(node->def.symbol);
            printf(" ");
            print_node(node->def.value);
            printf(")");
        } break;
        case NODE_BLOCK: {
            size_t n_expr = array_size(node->block.expr);
            printf("{");
            for (size_t i = 0; i < n_expr; ++i) {
                printf(" ");
                print_node(node->block.expr[i]);
            }
            printf(" }");
        } break;
        case NODE_IF: {
            printf("(if ");
            print_node(node->ifexpr.cond);
            printf(" ");
            print_node(node->ifexpr.expr_true);
            if (node->ifexpr.expr_false != NULL) {
                printf(" ");
                print_node(node->ifexpr.expr_false);
            }
            printf(")");
        } break;
        case NODE_FUN: {
            printf("(fun ");
            print_node(node->fun.name);
            printf(" (");
            size_t n_params = array_size(node->fun.param_names);
            for (size_t i = 0; i < n_params; ++i) {
                print_node(node->fun.param_names[i]);
                printf(":");
                print_node(node->fun.param_types[i]);
                if (i < n_params - 1) {
                    printf(" ");
                }
            }
            printf(")");
            printf(": ");
            print_node(node->fun.return_type);
            printf(" ");
            print_node(node->fun.body);
            printf(")");
        } break;
        default: { printf("{#unknown#}"); } break;
    }
}