aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/cc1/ast.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/cc1/ast.h')
-rw-r--r--src/cc1/ast.h433
1 files changed, 433 insertions, 0 deletions
diff --git a/src/cc1/ast.h b/src/cc1/ast.h
new file mode 100644
index 0000000..ef984a9
--- /dev/null
+++ b/src/cc1/ast.h
@@ -0,0 +1,433 @@
+#ifndef DUCC_AST_H
+#define DUCC_AST_H
+
+#include "../lib/ducc.h"
+#include "io.h"
+
+typedef enum {
+ StorageClass_unspecified,
+ StorageClass_auto,
+ StorageClass_constexpr,
+ StorageClass_extern,
+ StorageClass_register,
+ StorageClass_static,
+ StorageClass_thread_local,
+ StorageClass_typedef,
+} StorageClass;
+
+const char* storageclass_stringify(StorageClass s);
+
+typedef enum {
+ TypeKind_unknown,
+
+ TypeKind_void,
+ TypeKind_char,
+ TypeKind_schar,
+ TypeKind_uchar,
+ TypeKind_short,
+ TypeKind_ushort,
+ TypeKind_int,
+ TypeKind_uint,
+ TypeKind_long,
+ TypeKind_ulong,
+ TypeKind_llong,
+ TypeKind_ullong,
+ TypeKind_float,
+ TypeKind_double,
+ TypeKind_ldouble,
+ TypeKind_bool,
+ TypeKind_struct,
+ TypeKind_union,
+ TypeKind_enum,
+ TypeKind_ptr,
+ TypeKind_array,
+ TypeKind_func,
+} TypeKind;
+
+const char* type_kind_stringify(TypeKind k);
+
+struct AstNode;
+typedef struct AstNode AstNode;
+
+typedef struct {
+ AstNode* defs;
+ size_t index;
+} TypeRef;
+
+typedef struct Type {
+ TypeKind kind;
+ StorageClass storage_class;
+ // Check `base` instead of `kind` to test if the type is an array or a pointer.
+ struct Type* base;
+ int array_size;
+ TypeRef ref;
+ struct Type* result;
+ AstNode* params;
+} Type;
+
+Type* type_new(TypeKind kind);
+Type* type_dup(Type* src);
+Type* type_new_ptr(Type* base);
+Type* type_new_array(Type* elem, int size);
+Type* type_new_static_string(int len);
+Type* type_array_to_ptr(Type* ty);
+Type* type_new_func(Type* result, AstNode* params);
+bool type_is_unsized(Type* ty);
+bool type_is_unsigned(Type* ty);
+
+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);
+int type_alignof(Type* ty);
+
+int to_aligned(int n, int a);
+
+typedef enum {
+ AstNodeKind_unknown,
+ AstNodeKind_nop,
+
+ AstNodeKind_array_initializer,
+ AstNodeKind_assign_expr,
+ AstNodeKind_binary_expr,
+ AstNodeKind_break_stmt,
+ AstNodeKind_case_label,
+ AstNodeKind_cast_expr,
+ AstNodeKind_cond_expr,
+ AstNodeKind_continue_stmt,
+ AstNodeKind_default_label,
+ AstNodeKind_deref_expr,
+ AstNodeKind_do_while_stmt,
+ AstNodeKind_enum_def,
+ AstNodeKind_enum_member,
+ AstNodeKind_expr_stmt,
+ AstNodeKind_for_stmt,
+ AstNodeKind_func,
+ AstNodeKind_func_call,
+ AstNodeKind_func_decl,
+ AstNodeKind_func_def,
+ AstNodeKind_goto_stmt,
+ AstNodeKind_gvar,
+ AstNodeKind_gvar_decl,
+ AstNodeKind_if_stmt,
+ AstNodeKind_int_expr,
+ AstNodeKind_double_expr,
+ AstNodeKind_label_stmt,
+ 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_switch_stmt,
+ AstNodeKind_type,
+ AstNodeKind_typedef_decl,
+ AstNodeKind_unary_expr,
+ AstNodeKind_union_decl,
+ AstNodeKind_union_def,
+
+ // Intermediate ASTs: they are used only in parsing, not for parse result.
+ AstNodeKind_declarator,
+} AstNodeKind;
+
+const char* astnode_kind_stringify(AstNodeKind k);
+
+// Expression nodes
+typedef struct {
+ int value;
+} IntExprNode;
+
+typedef struct {
+ double value;
+} DoubleExprNode;
+
+typedef struct {
+ int idx;
+} StrExprNode;
+
+typedef struct {
+ int op;
+ AstNode* operand;
+} UnaryExprNode;
+
+typedef struct {
+ int op;
+ AstNode* lhs;
+ AstNode* rhs;
+} BinaryExprNode;
+
+typedef struct {
+ int op;
+ AstNode* lhs;
+ AstNode* rhs;
+} LogicalExprNode;
+
+typedef struct {
+ int op;
+ AstNode* lhs;
+ AstNode* rhs;
+} AssignExprNode;
+
+typedef struct {
+ AstNode* operand;
+} CastExprNode;
+
+typedef struct {
+ AstNode* cond;
+ AstNode* then;
+ AstNode* else_;
+} CondExprNode;
+
+typedef struct {
+ AstNode* operand;
+} DerefExprNode;
+
+typedef struct {
+ AstNode* operand;
+} RefExprNode;
+
+typedef struct {
+ AstNode* func;
+ AstNode* args;
+} FuncCallNode;
+
+// Statement nodes
+typedef struct {
+ AstNode* cond;
+ AstNode* then;
+ AstNode* else_;
+} IfStmtNode;
+
+typedef struct {
+ AstNode* init;
+ AstNode* cond;
+ AstNode* update;
+ AstNode* body;
+} ForStmtNode;
+
+typedef struct {
+ AstNode* cond;
+ AstNode* body;
+} DoWhileStmtNode;
+
+typedef struct {
+ AstNode* expr;
+ AstNode* body;
+} SwitchStmtNode;
+
+typedef struct {
+ int value;
+ AstNode* body;
+} CaseLabelNode;
+
+typedef struct {
+ AstNode* body;
+} DefaultLabelNode;
+
+typedef struct {
+ const char* name;
+ AstNode* body;
+} LabelStmtNode;
+
+typedef struct {
+ AstNode* expr;
+} ReturnStmtNode;
+
+typedef struct {
+ const char* label;
+} GotoStmtNode;
+
+typedef struct {
+ AstNode* expr;
+} ExprStmtNode;
+
+// Declaration nodes
+typedef struct {
+ const char* name;
+ AstNode* params;
+ AstNode* body;
+ int stack_size;
+} FuncDefNode;
+
+typedef struct {
+ const char* name;
+ int stack_offset;
+} LvarNode;
+
+typedef struct {
+ AstNode* expr;
+} LvarDeclNode;
+
+typedef struct {
+ const char* name;
+ int stack_offset;
+} ParamNode;
+
+typedef struct {
+ const char* name;
+ AstNode* expr;
+} GvarDeclNode;
+
+typedef struct {
+ const char* name;
+ AstNode* members;
+} StructDefNode;
+
+typedef struct {
+ const char* name;
+ AstNode* members;
+} UnionDefNode;
+
+typedef struct {
+ const char* name;
+ AstNode* members;
+} EnumDefNode;
+
+typedef struct {
+ const char* name;
+ int value;
+} EnumMemberNode;
+
+typedef struct {
+ const char* name;
+ AstNode* init;
+} DeclaratorNode;
+
+typedef struct {
+ const char* name;
+} FuncNode;
+
+typedef struct {
+ const char* name;
+} GvarNode;
+
+typedef struct {
+ const char* name;
+ bool is_bitfield;
+ int bitfield_offset;
+ int bitfield_width;
+} StructMemberNode;
+
+typedef struct {
+ const char* name;
+} TypedefDeclNode;
+
+typedef struct {
+ AstNode* list;
+} ArrayInitializerNode;
+
+typedef struct {
+ AstNode* items;
+ int len;
+ int cap;
+} ListNode;
+
+struct AstNode {
+ AstNodeKind kind;
+ // TODO: currently only limited set of ast nodes have loc field.
+ SourceLocation loc;
+ Type* ty;
+ union {
+ IntExprNode* int_expr;
+ DoubleExprNode* double_expr;
+ StrExprNode* str_expr;
+ UnaryExprNode* unary_expr;
+ BinaryExprNode* binary_expr;
+ LogicalExprNode* logical_expr;
+ AssignExprNode* assign_expr;
+ CastExprNode* cast_expr;
+ CondExprNode* cond_expr;
+ DerefExprNode* deref_expr;
+ RefExprNode* ref_expr;
+ FuncCallNode* func_call;
+ IfStmtNode* if_stmt;
+ ForStmtNode* for_stmt;
+ DoWhileStmtNode* do_while_stmt;
+ SwitchStmtNode* switch_stmt;
+ CaseLabelNode* case_label;
+ DefaultLabelNode* default_label;
+ LabelStmtNode* label_stmt;
+ ReturnStmtNode* return_stmt;
+ GotoStmtNode* goto_stmt;
+ ExprStmtNode* expr_stmt;
+ FuncDefNode* func_def;
+ LvarNode* lvar;
+ LvarDeclNode* lvar_decl;
+ ParamNode* param;
+ GvarDeclNode* gvar_decl;
+ StructDefNode* struct_def;
+ UnionDefNode* union_def;
+ EnumDefNode* enum_def;
+ EnumMemberNode* enum_member;
+ DeclaratorNode* declarator;
+ FuncNode* func;
+ GvarNode* gvar;
+ StructMemberNode* struct_member;
+ TypedefDeclNode* typedef_decl;
+ ArrayInitializerNode* array_initializer;
+ ListNode* list;
+ } as;
+};
+
+typedef struct {
+ AstNode* funcs;
+ AstNode* vars;
+ const char** str_literals;
+} Program;
+
+AstNode* ast_new(AstNodeKind kind);
+AstNode* ast_new_list(int capacity);
+void ast_append(AstNode* list, AstNode* item);
+AstNode* ast_new_int(int v);
+AstNode* ast_new_double(double v);
+AstNode* ast_new_unary_expr(int op, AstNode* operand);
+AstNode* ast_new_binary_expr(int op, AstNode* lhs, AstNode* rhs);
+
+AstNode* ast_new_assign_expr(int op, AstNode* lhs, AstNode* rhs);
+AstNode* ast_new_assign_add_expr(AstNode* lhs, AstNode* rhs);
+AstNode* ast_new_assign_sub_expr(AstNode* lhs, AstNode* rhs);
+AstNode* ast_new_ref_expr(AstNode* operand);
+AstNode* ast_new_deref_expr(AstNode* operand);
+AstNode* ast_new_member_access_expr(AstNode* obj, const char* name);
+AstNode* ast_new_cast_expr(AstNode* operand, Type* result_ty);
+AstNode* ast_new_logical_expr(int op, AstNode* lhs, AstNode* rhs);
+AstNode* ast_new_cond_expr(AstNode* cond, AstNode* then, AstNode* else_);
+AstNode* ast_new_str_expr(int idx, Type* ty);
+AstNode* ast_new_func_call(AstNode* func, AstNode* args);
+AstNode* ast_new_func(const char* name, Type* ty);
+AstNode* ast_new_gvar(const char* name, Type* ty);
+AstNode* ast_new_lvar(const char* name, int stack_offset, Type* ty);
+
+AstNode* ast_new_nop(void);
+AstNode* ast_new_break_stmt(void);
+AstNode* ast_new_continue_stmt(void);
+AstNode* ast_new_return_stmt(AstNode* expr);
+AstNode* ast_new_expr_stmt(AstNode* expr);
+AstNode* ast_new_if_stmt(AstNode* cond, AstNode* then, AstNode* else_);
+AstNode* ast_new_for_stmt(AstNode* init, AstNode* cond, AstNode* update, AstNode* body);
+AstNode* ast_new_do_while_stmt(AstNode* cond, AstNode* body);
+AstNode* ast_new_switch_stmt(AstNode* expr);
+AstNode* ast_new_case_label(int value, AstNode* body);
+AstNode* ast_new_default_label(AstNode* body);
+AstNode* ast_new_goto_stmt(const char* label);
+AstNode* ast_new_label_stmt(const char* name, AstNode* body);
+
+AstNode* ast_new_declarator(const char* name, Type* ty);
+AstNode* ast_new_func_def(const char* name, Type* ty, AstNode* params, AstNode* body, int stack_size);
+AstNode* ast_new_enum_member(const char* name, int value);
+AstNode* ast_new_typedef_decl(const char* name, Type* ty);
+AstNode* ast_new_struct_def(const char* name);
+AstNode* ast_new_union_def(const char* name);
+AstNode* ast_new_enum_def(const char* name);
+AstNode* ast_new_array_initializer(AstNode* list);
+
+#endif