aboutsummaryrefslogtreecommitdiff
path: root/src/ast.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-03-25 21:14:13 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2023-03-25 21:14:35 +0200
commit542be69b2a89eb35f87e208018a7c0cc4c2aac04 (patch)
tree4dd510c5020c963e1be460be65c8c53104dcf49d /src/ast.c
parenteaf2d360120a4cab12c27ed51961cd5d224042ff (diff)
downloadek-542be69b2a89eb35f87e208018a7c0cc4c2aac04.tar.gz
ek-542be69b2a89eb35f87e208018a7c0cc4c2aac04.zip
add union to parser
Diffstat (limited to 'src/ast.c')
-rw-r--r--src/ast.c72
1 files changed, 70 insertions, 2 deletions
diff --git a/src/ast.c b/src/ast.c
index 4b8e55a..1211c5e 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -436,7 +436,11 @@ struct ast_node *gen_type(enum ast_type_kind kind, struct ast_node *id,
case AST_TYPE_UNION:
n->_type.unio.id = id;
n->_type.unio.body = expr;
- n->loc = id->loc;
+ if (id)
+ n->loc = id->loc;
+ else
+ n->loc = expr->loc;
+
break;
case AST_TYPE_STRUCT:
@@ -666,7 +670,10 @@ struct ast_node *gen_struct(struct ast_node *id,
n->_struct.id = id;
n->_struct.generics = generics;
n->_struct.body = body;
- n->loc = id->loc;
+ if (id)
+ n->loc = id->loc;
+ else
+ n->loc = body->loc;
return n;
}
@@ -679,6 +686,30 @@ void destroy_struct(struct ast_node *struc)
free(struc);
}
+struct ast_node *gen_union(struct ast_node *id,
+ struct ast_node *generics, struct ast_node *body)
+{
+ ALLOC_NODE(n, struct);
+ n->node_type = AST_UNION;
+ n->_union.id = id;
+ n->_union.generics = generics;
+ n->_union.body = body;
+ if (id)
+ n->loc = id->loc;
+ else
+ n->loc = body->loc;
+ return n;
+}
+
+void destroy_union(struct ast_node *unio)
+{
+ assert(unio->node_type == AST_UNION);
+ destroy_ast_node(unio->_union.id);
+ DESTROY_LIST(unio->_union.generics);
+ DESTROY_LIST(unio->_union.body);
+ free(unio);
+}
+
struct ast_node *gen_enum(struct ast_node *id, struct ast_node *type,
struct ast_node *body)
{
@@ -866,6 +897,7 @@ void destroy_ast_node(struct ast_node *node)
assert(node->node_type);
switch (node->node_type) {
+ case AST_UNION: destroy_union(node); break;
case AST_ASSIGN: destroy_assign(node); break;
case AST_INIT: destroy_init(node); break;
case AST_SIZEOF: destroy_sizeof(node); break;
@@ -1022,6 +1054,18 @@ static void dump_flags(struct ast_node *node)
static void __dump_ast(int depth, struct ast_node *node)
{
switch (node->node_type) {
+ case AST_UNION:
+ dump(depth, "{UNION:");
+ dump_flags(node);
+ putchar('\n');
+
+ dump_ast(depth + 1, node->_union.id);
+ dump_ast(depth + 1, node->_union.generics);
+ dump_ast(depth + 1, node->_union.body);
+
+ dump(depth, "}\n");
+ break;
+
case AST_ASSIGN:
dump(depth, "{ASSIGN:");
dump_flags(node);
@@ -1494,6 +1538,12 @@ struct ast_node *clone_ast_node(struct ast_node *node)
assert(node->node_type);
struct ast_node *new = NULL;
switch (node->node_type) {
+ case AST_UNION:
+ new = gen_union(clone_ast_node(node->_union.id),
+ clone_ast_node(node->_union.generics),
+ clone_ast_node(node->_union.body));
+ break;
+
case AST_ASSIGN:
new = gen_assign(clone_ast_node(node->_assign.to),
clone_ast_node(node->_assign.from));
@@ -1814,6 +1864,18 @@ int identical_ast_nodes(int exact, struct ast_node *left, struct ast_node *right
return 0;
switch (left->node_type) {
+ case AST_UNION:
+ if (!identical_ast_nodes(exact, left->_union.id, right->_union.id))
+ return 0;
+
+ if (!identical_ast_nodes(exact, left->_union.generics, right->_union.generics))
+ return 0;
+
+ if (!identical_ast_nodes(exact, left->_union.body, right->_union.body))
+ return 0;
+
+ break;
+
case AST_ASSIGN:
if (!identical_ast_nodes(exact, left->_assign.to, right->_assign.to))
return 0;
@@ -2267,6 +2329,12 @@ int ast_call_on(int (*call)(struct ast_node *, void *data),
return ret;
switch (node->node_type) {
+ case AST_UNION:
+ ret |= call(node->_union.id, data);
+ ret |= call(node->_union.generics, data);
+ ret |= call(node->_union.body, data);
+ break;
+
case AST_ASSIGN:
ret |= call(node->_assign.to, data);
ret |= call(node->_assign.from, data);