Cthulhu  0.2.10
Cthulhu compiler collection
function.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-3.0-only
2 
5 
6 #include "ctu/sema/sema.h"
7 #include "ctu/sema/type.h"
8 #include "ctu/sema/expr.h"
9 
10 #include "cthulhu/util/types.h"
11 
12 #include "cthulhu/tree/query.h"
13 
14 #include "memory/memory.h"
15 #include "std/vector.h"
16 
17 static void add_param(ctu_sema_t *sema, tree_t *param)
18 {
19  const tree_t *ty = tree_get_type(param);
20  const char *id = tree_get_name(param);
21  const node_t *node = tree_get_node(param);
22 
23  // if (!tree_is(ty, eTreeTypeStruct))
24  // {
25  // ctu_add_decl(sema->sema, eCtuTagValues, id, param);
26  // return;
27  // }
28 
29  tree_t *ref = tree_type_reference(node, id, ty);
30 
31  tree_storage_t storage = {
32  .storage = ty,
33  .length = 1,
34  .quals = eQualMutable
35  };
36  tree_t *local = tree_decl_local(node, id, storage, ref);
37  tree_add_local(sema->decl, local);
38  ctu_add_decl(sema->sema, eCtuTagValues, id, local);
39 
40  tree_t *init = tree_stmt_assign(node, local, param);
41  vector_push(&sema->block, init);
42 }
43 
44 void ctu_resolve_function(tree_t *sema, tree_t *self, void *user)
45 {
46  ctu_t *decl = begin_resolve(sema, self, user, eCtuDeclFunction);
47  tree_t *fn = tree_resolve_type(tree_get_cookie(sema), self);
48  if (tree_is(fn, eTreeError)) { return; }
49 
50  const node_t *node = tree_get_node(fn);
51  const vector_t *params = tree_fn_get_params(fn);
52  const tree_t *return_type = tree_fn_get_return(fn);
53 
54  size_t len = vector_len(params);
55  const size_t sizes[eCtuTagTotal] = {
56  [eCtuTagValues] = len
57  };
58 
59  arena_t *arena = get_global_arena();
60  tree_t *ctx = tree_module(sema, decl->node, decl->name, eCtuTagTotal, sizes);
61  ctu_sema_t inner = ctu_sema_init(ctx, fn, vector_new(0, arena));
62 
63  for (size_t i = 0; i < len; i++)
64  {
65  tree_t *param = vector_get(params, i);
66  add_param(&inner, param);
67  }
68 
69  ctu_t *fn_body = decl->body;
70 
71  if (fn_body == NULL)
72  {
73  tree_close_function(fn, NULL);
74  return;
75  }
76 
77  tree_t *body = ctu_sema_stmt(&inner, fn_body);
78  vector_push(&inner.block, body);
79 
80  if (fn_body->kind == eCtuStmtList)
81  {
82  if (util_types_equal(return_type, ctu_get_void_type()))
83  {
84  tree_t *ret = tree_stmt_return(node, tree_expr_unit(node, return_type));
85  vector_push(&inner.block, ret);
86  }
87  }
88 
89  tree_t *block = tree_stmt_block(node, inner.block);
90  tree_close_function(self, block);
91 }
92 
93 void ctu_resolve_function_type(tree_t *sema, tree_t *self, void *user)
94 {
95  ctu_t *decl = begin_resolve(sema, self, user, eCtuDeclFunction);
96  arena_t *arena = get_global_arena();
97  ctu_sema_t inner = ctu_sema_init(sema, NULL, vector_new(0, arena));
98 
99  size_t len = vector_len(decl->params);
100  vector_t *params = vector_of(len, arena);
101  for (size_t i = 0; i < len; i++)
102  {
103  ctu_t *param = vector_get(decl->params, i);
104  tree_t *type = ctu_sema_type(&inner, param->param_type);
105  tree_t *it = tree_decl_param(param->node, param->name, type);
106  vector_set(params, i, it);
107  }
108 
109  tree_arity_t arity = (decl->variadic != NULL) ? eArityVariable : eArityFixed;
110  tree_t *return_type = decl->return_type == NULL
112  : ctu_sema_type(&inner, decl->return_type);
113 
114  tree_t *signature = tree_type_closure(decl->node, decl->name, return_type, params, arity);
115 
116  tree_set_type(self, signature);
117  self->params = params;
118 }
CT_PUREFN CT_TREE_API const node_t * tree_get_node(const tree_t *tree)
Definition: context.c:94
CT_PUREFN CT_TREE_API const char * tree_get_name(const tree_t *tree)
Definition: context.c:102
CT_PUREFN CT_TREE_API const tree_t * tree_get_type(const tree_t *tree)
Definition: context.c:132
CT_PUREFN CT_TREE_API bool tree_is(const tree_t *self, tree_kind_t kind)
Definition: query.c:91
CT_PUREFN CT_TREE_API const tree_t * tree_fn_get_return(const tree_t *self)
Definition: query.c:167
CT_PUREFN CT_TREE_API const vector_t * tree_fn_get_params(const tree_t *self)
Definition: query.c:179
@ eCtuStmtList
Definition: ast.h:48
@ eCtuDeclFunction
Definition: ast.h:66
tree_t * ctu_sema_stmt(ctu_sema_t *sema, const ctu_t *stmt)
Definition: expr.c:908
@ eCtuTagTotal
Definition: sema.h:17
void ctu_add_decl(tree_t *sema, ctu_tag_t tag, const char *name, tree_t *decl)
Definition: sema.c:129
ctu_sema_t ctu_sema_init(tree_t *sema, tree_t *decl, vector_t *block)
Definition: sema.c:21
tree_t * ctu_get_void_type(void)
Definition: sema.c:209
tree_t * ctu_sema_type(ctu_sema_t *sema, const ctu_t *type)
Definition: type.c:114
void ctu_resolve_function(tree_t *sema, tree_t *self, void *user)
Definition: function.c:44
void ctu_resolve_function_type(tree_t *sema, tree_t *self, void *user)
Definition: function.c:93
CT_MEMORY_API arena_t * get_global_arena(void)
get the global memory arena
Definition: memory.c:16
CT_BEGIN_API CT_UTIL_API bool util_types_equal(const tree_t *lhs, const tree_t *rhs)
compare two types for strict equality compares two types for exact equality, does not follow typedefs
Definition: util.c:33
tree_arity_t
all arities
Definition: ops.h:64
CT_TREE_API tree_t * tree_expr_unit(const node_t *node, const tree_t *type)
Definition: tree.c:203
CT_TREE_API tree_t * tree_type_reference(const node_t *node, const char *name, const tree_t *reference)
create a reference type
Definition: tree.c:185
CT_TREE_API tree_t * tree_type_closure(const node_t *node, const char *name, const tree_t *result, const vector_t *params, tree_arity_t arity)
create a function pointer type
Definition: tree.c:146
CT_TREE_API tree_t * tree_module(tree_t *parent, const node_t *node, const char *name, size_t decls, const size_t *sizes)
create a new module
Definition: sema.c:52
CT_TREE_API void tree_close_function(tree_t *self, tree_t *body)
Definition: decl.c:168
CT_TREE_API tree_t * tree_stmt_return(const node_t *node, const tree_t *value)
create a return statement
Definition: tree.c:368
CT_TREE_API tree_cookie_t * tree_get_cookie(tree_t *sema)
return a resolution cookie
Definition: sema.c:136
CT_TREE_API tree_t * tree_decl_param(const node_t *node, const char *name, const tree_t *type)
Definition: decl.c:188
CT_TREE_API tree_t * tree_resolve_type(tree_cookie_t *cookie, const tree_t *decl)
Definition: decl.c:102
CT_TREE_API tree_t * tree_stmt_assign(const node_t *node, tree_t *dst, const tree_t *src)
Definition: tree.c:391
CT_TREE_API tree_t * tree_stmt_block(const node_t *node, const vector_t *stmts)
create a block statement
Definition: tree.c:359
CT_TREE_API void tree_set_type(tree_t *self, const tree_t *type)
Definition: context.c:150
CT_TREE_API void tree_add_local(tree_t *self, tree_t *decl)
Definition: decl.c:243
CT_TREE_API tree_t * tree_decl_local(const node_t *node, const char *name, tree_storage_t storage, const tree_t *type)
Definition: decl.c:198
CT_NODISCARD CT_PUREFN CT_STD_API void * vector_get(const vector_t *vector, size_t index)
get a value from a vector
Definition: vector.c:134
CT_NODISCARD CT_STD_API vector_t * vector_new(size_t size, arena_t *arena)
create a new vector with an initial capacity
Definition: vector.c:63
CT_NODISCARD CT_STD_API vector_t * vector_of(size_t len, arena_t *arena)
create a new vector with a specified length
Definition: vector.c:71
CT_STD_API void vector_push(vector_t **vector, void *value)
push a value onto the end of a vector
Definition: vector.c:108
CT_STD_API void vector_set(vector_t *vector, size_t index, void *value)
set a value in a vector
Definition: vector.c:125
CT_NODISCARD CT_PUREFN CT_STD_API size_t vector_len(const vector_t *vector)
get the length of a vector
Definition: vector.c:152
ctu_t * begin_resolve(tree_t *sema, tree_t *self, void *user, ctu_kind_t kind)
Definition: resolve.c:12
an allocator object
Definition: arena.h:86
vector_t * block
current statement block
Definition: sema.h:27
tree_t * decl
current decl
Definition: sema.h:26
tree_t * sema
current scope
Definition: sema.h:25
Definition: ast.h:86
ctu_t * body
Definition: ast.h:119
ctu_kind_t kind
Definition: ast.h:87
const vector_t * params
Definition: ast.h:116
ctu_t * param_type
Definition: ast.h:135
ctu_t * return_type
Definition: ast.h:118
const node_t * node
Definition: ast.h:88
char * variadic
Definition: ast.h:117
char * name
Definition: ast.h:92
a position in a source file
Definition: node.h:23
storage for a value
Definition: context.h:23
const tree_t * storage
the underlying storage type
Definition: context.h:25
Definition: tree.h:67
size_t length
Definition: tree.h:174
a generic vector of pointers
Definition: vector.c:16