aboutsummaryrefslogtreecommitdiffhomepage
path: root/ast.c
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-08-22 23:28:25 +0900
committernsfisis <nsfisis@gmail.com>2025-08-22 23:28:25 +0900
commit9c202a496e75903fe37e5c19cb97c98eba6e35f2 (patch)
tree52de494a4717a3c30c4bacb9dd9b91980be2a575 /ast.c
parent0ac6ac95283735dd70ebf55b26ef78a4c32c31de (diff)
downloadducc-9c202a496e75903fe37e5c19cb97c98eba6e35f2.tar.gz
ducc-9c202a496e75903fe37e5c19cb97c98eba6e35f2.tar.zst
ducc-9c202a496e75903fe37e5c19cb97c98eba6e35f2.zip
chore: move *.c and *.h files to src/
Diffstat (limited to 'ast.c')
-rw-r--r--ast.c475
1 files changed, 0 insertions, 475 deletions
diff --git a/ast.c b/ast.c
deleted file mode 100644
index 66f7cc2..0000000
--- a/ast.c
+++ /dev/null
@@ -1,475 +0,0 @@
-enum TypeKind {
- TypeKind_unknown,
-
- TypeKind_char,
- TypeKind_short,
- TypeKind_int,
- TypeKind_long,
- TypeKind_void,
- TypeKind_ptr,
- TypeKind_array,
- TypeKind_enum,
- TypeKind_struct,
- TypeKind_union,
-};
-typedef enum TypeKind TypeKind;
-
-const char* type_kind_stringify(TypeKind k) {
- if (k == TypeKind_unknown)
- return "<unknown>";
- else if (k == TypeKind_char)
- return "char";
- else if (k == TypeKind_short)
- return "short";
- else if (k == TypeKind_int)
- return "int";
- else if (k == TypeKind_long)
- return "long";
- else if (k == TypeKind_void)
- return "void";
- else if (k == TypeKind_ptr)
- return "<pointer>";
- else if (k == TypeKind_array)
- return "<array>";
- else if (k == TypeKind_enum)
- return "enum";
- else if (k == TypeKind_struct)
- return "struct";
- else if (k == TypeKind_union)
- return "union";
- else
- unreachable();
-}
-
-struct AstNode;
-
-struct Type {
- TypeKind kind;
- // Check `base` instead of `kind` to test if the type is an array or a pointer.
- struct Type* base;
- int array_size;
- struct AstNode* def;
-};
-typedef struct Type Type;
-
-void type_dump(Type* ty) {
- fprintf(stderr, "Type {\n");
- fprintf(stderr, " kind = %s\n", type_kind_stringify(ty->kind));
- fprintf(stderr, "}\n");
-}
-
-Type* type_new(TypeKind kind) {
- Type* ty = calloc(1, sizeof(Type));
- ty->kind = kind;
- return ty;
-}
-
-Type* type_new_ptr(Type* base) {
- Type* ty = calloc(1, sizeof(Type));
- ty->kind = TypeKind_ptr;
- ty->base = base;
- return ty;
-}
-
-Type* type_new_array(Type* elem, int size) {
- Type* ty = calloc(1, sizeof(Type));
- ty->kind = TypeKind_array;
- ty->base = elem;
- ty->array_size = size;
- return ty;
-}
-
-Type* type_new_static_string(int len) {
- return type_new_array(type_new(TypeKind_char), len + 1);
-}
-
-Type* type_array_to_ptr(Type* ty) {
- return type_new_ptr(ty->base);
-}
-
-BOOL type_is_unsized(Type* ty) {
- return ty->kind == TypeKind_void;
-}
-
-int type_sizeof_struct(Type* ty);
-int type_sizeof_union(Type* ty);
-int type_alignof_struct(Type* ty);
-int type_alignof_union(Type* ty);
-int type_offsetof(Type* ty, const char* name);
-Type* type_member_typeof(Type* ty, const char* name);
-
-int type_sizeof(Type* ty) {
- if (type_is_unsized(ty)) {
- fatal_error("type_sizeof: type size cannot be determined");
- }
-
- if (ty->kind == TypeKind_ptr)
- return 8;
- else if (ty->kind == TypeKind_char)
- return 1;
- else if (ty->kind == TypeKind_short)
- return 2;
- else if (ty->kind == TypeKind_int)
- return 4;
- else if (ty->kind == TypeKind_long)
- return 8;
- else if (ty->kind == TypeKind_enum)
- return 4;
- else if (ty->kind == TypeKind_array)
- return type_sizeof(ty->base) * ty->array_size;
- else if (ty->kind == TypeKind_struct)
- return type_sizeof_struct(ty);
- else if (ty->kind == TypeKind_union)
- return type_sizeof_union(ty);
- else
- unreachable();
-}
-
-int type_alignof(Type* ty) {
- if (type_is_unsized(ty)) {
- fatal_error("type_alignof: type size cannot be determined");
- }
-
- if (ty->kind == TypeKind_ptr)
- return 8;
- else if (ty->kind == TypeKind_char)
- return 1;
- else if (ty->kind == TypeKind_short)
- return 2;
- else if (ty->kind == TypeKind_int)
- return 4;
- else if (ty->kind == TypeKind_long)
- return 8;
- else if (ty->kind == TypeKind_enum)
- return 4;
- else if (ty->kind == TypeKind_array)
- return type_alignof(ty->base);
- else if (ty->kind == TypeKind_struct)
- return type_alignof_struct(ty);
- else if (ty->kind == TypeKind_union)
- return type_alignof_union(ty);
- else
- unreachable();
-}
-
-int to_aligned(int n, int a) {
- return (n + a - 1) / a * a;
-}
-
-enum AstNodeKind {
- AstNodeKind_unknown,
- AstNodeKind_nop,
-
- AstNodeKind_assign_expr,
- AstNodeKind_binary_expr,
- AstNodeKind_break_stmt,
- AstNodeKind_cond_expr,
- AstNodeKind_continue_stmt,
- AstNodeKind_deref_expr,
- AstNodeKind_do_while_stmt,
- AstNodeKind_enum_def,
- AstNodeKind_enum_member,
- AstNodeKind_expr_stmt,
- AstNodeKind_for_stmt,
- AstNodeKind_func_call,
- AstNodeKind_func_decl,
- AstNodeKind_func_def,
- AstNodeKind_gvar,
- AstNodeKind_gvar_decl,
- AstNodeKind_if_stmt,
- AstNodeKind_int_expr,
- AstNodeKind_list,
- AstNodeKind_logical_expr,
- AstNodeKind_lvar,
- AstNodeKind_lvar_decl,
- AstNodeKind_param,
- AstNodeKind_ref_expr,
- AstNodeKind_return_stmt,
- AstNodeKind_str_expr,
- AstNodeKind_struct_decl,
- AstNodeKind_struct_def,
- AstNodeKind_struct_member,
- AstNodeKind_type,
- AstNodeKind_typedef_decl,
- AstNodeKind_unary_expr,
- AstNodeKind_union_decl,
- AstNodeKind_union_def,
- AstNodeKind_union_member,
-
- // Intermediate ASTs: they are used only in parsing, not for parse result.
- AstNodeKind_declarator,
-};
-typedef enum AstNodeKind AstNodeKind;
-
-#define node_items __n1
-#define node_len __i1
-#define node_cap __i2
-#define node_expr __n1
-#define node_lhs __n1
-#define node_rhs __n2
-#define node_operand __n1
-#define node_cond __n1
-#define node_init __n2
-#define node_update __n3
-#define node_then __n2
-#define node_else __n3
-#define node_body __n4
-#define node_members __n1
-#define node_params __n1
-#define node_args __n1
-#define node_int_value __i1
-#define node_idx __i1
-#define node_op __i1
-#define node_stack_offset __i1
-#define node_stack_size __i1
-
-struct AstNode {
- AstNodeKind kind;
- const char* name;
- Type* ty;
- struct AstNode* __n1;
- struct AstNode* __n2;
- struct AstNode* __n3;
- struct AstNode* __n4;
- int __i1;
- int __i2;
-};
-typedef struct AstNode AstNode;
-
-struct Program {
- AstNode* funcs;
- AstNode* vars;
- const char** str_literals;
-};
-typedef struct Program Program;
-
-AstNode* ast_new(AstNodeKind kind) {
- AstNode* ast = calloc(1, sizeof(AstNode));
- ast->kind = kind;
- return ast;
-}
-
-AstNode* ast_new_list(int capacity) {
- if (capacity == 0)
- unreachable();
- AstNode* list = ast_new(AstNodeKind_list);
- list->node_cap = capacity;
- list->node_len = 0;
- list->node_items = calloc(list->node_cap, sizeof(AstNode));
- return list;
-}
-
-void ast_append(AstNode* list, AstNode* item) {
- if (list->kind != AstNodeKind_list) {
- fatal_error("ast_append: ast is not a list");
- }
- if (!item) {
- return;
- }
- if (list->node_cap <= list->node_len) {
- list->node_cap *= 2;
- list->node_items = realloc(list->node_items, sizeof(AstNode) * list->node_cap);
- memset(list->node_items + list->node_len, 0, sizeof(AstNode) * (list->node_cap - list->node_len));
- }
- memcpy(list->node_items + list->node_len, item, sizeof(AstNode));
- ++list->node_len;
-}
-
-AstNode* ast_new_int(int v) {
- AstNode* e = ast_new(AstNodeKind_int_expr);
- e->node_int_value = v;
- e->ty = type_new(TypeKind_int);
- return e;
-}
-
-AstNode* ast_new_unary_expr(int op, AstNode* operand) {
- AstNode* e = ast_new(AstNodeKind_unary_expr);
- e->node_op = op;
- e->node_operand = operand;
- e->ty = type_new(TypeKind_int);
- return e;
-}
-
-AstNode* ast_new_binary_expr(int op, AstNode* lhs, AstNode* rhs) {
- AstNode* e = ast_new(AstNodeKind_binary_expr);
- e->node_op = op;
- e->node_lhs = lhs;
- e->node_rhs = rhs;
- if (op == TokenKind_plus) {
- if (lhs->ty->kind == TypeKind_ptr) {
- e->ty = lhs->ty;
- } else if (lhs->ty->kind == TypeKind_array) {
- e->ty = type_array_to_ptr(lhs->ty);
- } else if (rhs->ty->kind == TypeKind_ptr) {
- e->ty = rhs->ty;
- } else if (rhs->ty->kind == TypeKind_array) {
- e->ty = type_array_to_ptr(rhs->ty);
- } else {
- e->ty = type_new(TypeKind_int);
- }
- } else if (op == TokenKind_minus) {
- if (lhs->ty->kind == TypeKind_ptr) {
- e->ty = lhs->ty;
- } else if (lhs->ty->kind == TypeKind_array) {
- e->ty = type_array_to_ptr(lhs->ty);
- } else {
- e->ty = type_new(TypeKind_int);
- }
- } else {
- e->ty = type_new(TypeKind_int);
- }
- return e;
-}
-
-AstNode* ast_new_assign_expr(int op, AstNode* lhs, AstNode* rhs) {
- AstNode* e = ast_new(AstNodeKind_assign_expr);
- e->node_op = op;
- e->node_lhs = lhs;
- e->node_rhs = rhs;
- e->ty = lhs->ty;
- return e;
-}
-
-AstNode* ast_new_assign_add_expr(AstNode* lhs, AstNode* rhs) {
- if (lhs->ty->base) {
- rhs = ast_new_binary_expr(TokenKind_star, rhs, ast_new_int(type_sizeof(lhs->ty->base)));
- } else if (rhs->ty->base) {
- lhs = ast_new_binary_expr(TokenKind_star, lhs, ast_new_int(type_sizeof(rhs->ty->base)));
- }
- return ast_new_assign_expr(TokenKind_assign_add, lhs, rhs);
-}
-
-AstNode* ast_new_assign_sub_expr(AstNode* lhs, AstNode* rhs) {
- if (lhs->ty->base) {
- rhs = ast_new_binary_expr(TokenKind_star, rhs, ast_new_int(type_sizeof(lhs->ty->base)));
- }
- return ast_new_assign_expr(TokenKind_assign_sub, lhs, rhs);
-}
-
-AstNode* ast_new_ref_expr(AstNode* operand) {
- AstNode* e = ast_new(AstNodeKind_ref_expr);
- e->node_operand = operand;
- e->ty = type_new_ptr(operand->ty);
- return e;
-}
-
-AstNode* ast_new_deref_expr(AstNode* operand) {
- AstNode* e = ast_new(AstNodeKind_deref_expr);
- e->node_operand = operand;
- e->ty = operand->ty->base;
- return e;
-}
-
-AstNode* ast_new_member_access_expr(AstNode* obj, const char* name) {
- AstNode* e = ast_new(AstNodeKind_deref_expr);
- e->node_operand = ast_new_binary_expr(TokenKind_plus, obj, ast_new_int(type_offsetof(obj->ty->base, name)));
- e->ty = type_member_typeof(obj->ty->base, name);
- e->node_operand->ty = type_new_ptr(e->ty);
- return e;
-}
-
-int type_sizeof_struct(Type* ty) {
- int next_offset = 0;
- int struct_align = 0;
-
- for (int i = 0; i < ty->def->node_members->node_len; ++i) {
- AstNode* member = ty->def->node_members->node_items + i;
- int size = type_sizeof(member->ty);
- int align = type_alignof(member->ty);
-
- next_offset = to_aligned(next_offset, align);
- next_offset += size;
- if (struct_align < align) {
- struct_align = align;
- }
- }
- return to_aligned(next_offset, struct_align);
-}
-
-int type_sizeof_union(Type* ty) {
- int union_size = 0;
- int union_align = 0;
-
- for (int i = 0; i < ty->def->node_members->node_len; ++i) {
- AstNode* member = ty->def->node_members->node_items + i;
- int size = type_sizeof(member->ty);
- int align = type_alignof(member->ty);
-
- size = to_aligned(size, align);
- if (union_size < size) {
- union_size = size;
- }
- if (union_align < align) {
- union_align = align;
- }
- }
- return to_aligned(union_size, union_align);
-}
-
-int type_alignof_struct(Type* ty) {
- int struct_align = 0;
-
- for (int i = 0; i < ty->def->node_members->node_len; ++i) {
- AstNode* member = ty->def->node_members->node_items + i;
- int align = type_alignof(member->ty);
-
- if (struct_align < align) {
- struct_align = align;
- }
- }
- return struct_align;
-}
-
-int type_alignof_union(Type* ty) {
- int union_align = 0;
-
- for (int i = 0; i < ty->def->node_members->node_len; ++i) {
- AstNode* member = ty->def->node_members->node_items + i;
- int align = type_alignof(member->ty);
-
- if (union_align < align) {
- union_align = align;
- }
- }
- return union_align;
-}
-
-int type_offsetof(Type* ty, const char* name) {
- if (ty->kind == TypeKind_union) {
- return 0;
- }
- if (ty->kind != TypeKind_struct) {
- fatal_error("type_offsetof: type is neither a struct nor a union");
- }
-
- int next_offset = 0;
-
- for (int i = 0; i < ty->def->node_members->node_len; ++i) {
- AstNode* member = ty->def->node_members->node_items + i;
- int size = type_sizeof(member->ty);
- int align = type_alignof(member->ty);
-
- next_offset = to_aligned(next_offset, align);
- if (strcmp(member->name, name) == 0) {
- return next_offset;
- }
- next_offset += size;
- }
-
- fatal_error("type_offsetof: member not found");
-}
-
-Type* type_member_typeof(Type* ty, const char* name) {
- if (ty->kind != TypeKind_struct && ty->kind != TypeKind_union) {
- fatal_error("type_member_typeof: type is neither a struct nor a union");
- }
-
- for (int i = 0; i < ty->def->node_members->node_len; ++i) {
- AstNode* member = ty->def->node_members->node_items + i;
- if (strcmp(member->name, name) == 0) {
- return member->ty;
- }
- }
-
- fatal_error("type_offsetof: member not found");
-}