aboutsummaryrefslogtreecommitdiff
path: root/src/formatter/types.c
blob: 670405f6578c5304f234c51c9d1aa22afb5d242e (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
// Logic for formatting types

#include "../ast.h"
#include "../stdlib/datatypes.h"
#include "../stdlib/stdlib.h"
#include "../stdlib/text.h"
#include "args.h"
#include "formatter.h"

Text_t format_type(type_ast_t *type) {
    switch (type->tag) {
    case VarTypeAST: return Text$from_str(Match(type, VarTypeAST)->name);
    case PointerTypeAST: {
        DeclareMatch(ptr, type, PointerTypeAST);
        return Texts(ptr->is_stack ? Text("&") : Text("@"), format_type(ptr->pointed));
    }
    case ListTypeAST: {
        return Texts("[", format_type(Match(type, ListTypeAST)->item), "]");
    }
    case TableTypeAST: {
        DeclareMatch(table, type, TableTypeAST);
        Text_t code = Texts("{", format_type(table->key), ":", format_type(table->value));
        if (table->default_value) {
            OptionalText_t val = format_inline_code(table->default_value, (Table_t){});
            assert(val.tag != TEXT_NONE);
            code = Texts(code, "=", val);
        }
        return Texts(code, "}");
    }
    case FunctionTypeAST: {
        DeclareMatch(func, type, FunctionTypeAST);
        Text_t code = Texts("func(", format_inline_args(func->args, (Table_t){}));
        if (func->ret) code = Texts(code, func->args ? Text(" -> ") : Text("-> "), format_type(func->ret));
        return Texts(code, ")");
    }
    case OptionalTypeAST: {
        return Texts(format_type(Match(type, OptionalTypeAST)->type), "?");
    }
    case UnknownTypeAST:
    default: fail("Invalid Type AST");
    }
}