diff --git a/stage1/spl_ast.c b/stage1/spl_ast.c index b547d54..b604900 100644 --- a/stage1/spl_ast.c +++ b/stage1/spl_ast.c @@ -409,7 +409,7 @@ static spl_ast_node_ref_t parse_type_decl(parser_t *p, spl_ast_node_ref_vec_t at if (t && (t->type == TOK_COMMA || t->type == TOK_SEMICOLON)) { advance(p); } else { - LOG_WARN("need comma or semicolon with member decl"); + SPL_WARN(t, "need comma or semicolon with member decl"); } return ref; } @@ -434,7 +434,7 @@ static spl_ast_node_ref_t parse_member_decl(parser_t *p, spl_ast_node_ref_vec_t if (t && (t->type == TOK_COMMA || t->type == TOK_SEMICOLON)) { advance(p); } else { - LOG_WARN("need comma or semicolon with member decl"); + SPL_WARN(t, "need comma or semicolon with member decl"); } return ref; } @@ -484,7 +484,7 @@ static spl_ast_node_ref_t parse_var_const_decl(parser_t *p, spl_ast_node_ref_vec if (t && t->type == TOK_SEMICOLON) { advance(p); } else { - LOG_WARN("need semicolon in decl var/const"); + SPL_WARN(t, "need semicolon in decl var/const"); } return ref; } @@ -1867,8 +1867,10 @@ static void dump_node(spl_ast_t *ast, spl_ast_node_ref_t node_ref, dump_stack_t case SPL_AST_FN_DEFINE: dump_vec(ast, node->fn_decl.attr_list, stack); dump_vec(ast, node->fn_decl.param_list, stack); - if (node->fn_decl.type_expr) - dump_node(ast, node->fn_decl.type_expr, stack, 1); + if (node->fn_decl.type_expr) { + last = node->kind == SPL_AST_FN_DECL ? 1 : 0; + dump_node(ast, node->fn_decl.type_expr, stack, last); + } dump_vec(ast, node->fn_decl.block, stack); break; diff --git a/stage1/spl_ast.h b/stage1/spl_ast.h index d991210..fabe367 100644 --- a/stage1/spl_ast.h +++ b/stage1/spl_ast.h @@ -139,7 +139,10 @@ struct spl_ast_node { spl_ast_node_kind_t kind; spl_dbg_node_t dbg; - usize resolved_def_id; + union { + usize resolved_def_id; + usize resolved_type_id; + }; union { spl_ast_node_ref_vec_t container_members; /* container_decl */ diff --git a/stage1/spl_dbg.h b/stage1/spl_dbg.h index ea39824..679f06f 100644 --- a/stage1/spl_dbg.h +++ b/stage1/spl_dbg.h @@ -10,8 +10,16 @@ typedef struct { // TODO } spl_dbg_node_t; -#define SPL_FATAL(tok, fmt, ...) \ - LOG_FATAL("fatal at %s:%zd:%zd " fmt, ((tok) && (tok)->fname ? (tok)->fname : ""), \ - ((tok) ? (tok)->line : 0), ((tok) ? (tok)->col : 0), ##__VA_ARGS__) +#define SPL_FATAL(dbg, fmt, ...) \ + LOG_FATAL("fatal at %s:%zd:%zd " fmt, ((dbg) && (dbg)->fname ? (dbg)->fname : ""), \ + ((dbg) ? (dbg)->line : 0), ((dbg) ? (dbg)->col : 0), ##__VA_ARGS__) + +#define SPL_ERROR(dbg, fmt, ...) \ + LOG_ERROR("error at %s:%zd:%zd " fmt, ((dbg) && (dbg)->fname ? (dbg)->fname : ""), \ + ((dbg) ? (dbg)->line : 0), ((dbg) ? (dbg)->col : 0), ##__VA_ARGS__) + +#define SPL_WARN(dbg, fmt, ...) \ + LOG_ERROR("warn at %s:%zd:%zd " fmt, ((dbg) && (dbg)->fname ? (dbg)->fname : ""), \ + ((dbg) ? (dbg)->line : 0), ((dbg) ? (dbg)->col : 0), ##__VA_ARGS__) #endif /* __SPL_DBG_H__ */ diff --git a/stage1/spl_ir.h b/stage1/spl_ir.h index 8544b9b..661f265 100644 --- a/stage1/spl_ir.h +++ b/stage1/spl_ir.h @@ -222,7 +222,7 @@ typedef struct { SPL_IR_ATTR_NAKED, /* 不实现 */ SPL_IR_ATTR_NOINLINE, /* 不实现 */ SPL_IR_ATTR_ALWAYSINLINE, /* 不实现 */ - }; + } kind; } spl_ir_attr_t; typedef VEC(spl_ir_attr_t) spl_ir_attr_vec_t; diff --git a/stage1/spl_sema.c b/stage1/spl_sema.c index 22fc35e..9d4b5b9 100644 --- a/stage1/spl_sema.c +++ b/stage1/spl_sema.c @@ -1,7 +1,5 @@ #include "spl_sema.h" -// Scope part - void spl_scope_init(spl_scope_t *scope) { vec_init(scope->scopes); vec_push(scope->scopes, (spl_scope_node_t){0}); @@ -32,7 +30,7 @@ bool spl_scope_insert(spl_scope_t *scope, spl_scope_id_t id, spl_symbol_t symbol spl_scope_node_t *node = &vec_at(scope->scopes, id); if (map_get(node->symbols, symbol.name, &old)) { // spl_type_def(sema->type, old); TODO debug node - LOG_ERROR("find same symbol %s", symbol.name); + SPL_ERROR(&(spl_dbg_node_t){0}, "find same symbol %s", symbol.name); return false; } map_put(node->symbols, symbol.name, symbol); @@ -43,17 +41,14 @@ bool spl_scope_find(spl_scope_t *scope, const char *name, spl_symbol_t *out) { if (scope == NULL || name == NULL || out == NULL) { return false; } - for (spl_scope_node_t *s = &vec_at(scope->scopes, scope->current_scope); s != 0; - s = &vec_at(scope->scopes, s->parent)) { - if (map_get(s->symbols, name, out) == true) { + for (spl_scope_id_t id = scope->current_scope; id != 0; id = vec_at(scope->scopes, id).parent) { + spl_scope_node_t *s = &vec_at(scope->scopes, id); + if (map_get(s->symbols, name, out)) { Assert(out->kind != SPL_SYMBOL_KIND_ERROR); - break; + return true; } } - if (out->kind == SPL_SYMBOL_KIND_ERROR) { - return false; - } - return true; + return false; } // Parse once @@ -61,7 +56,6 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { Assert(sema != NULL && ref != 0); spl_ast_node_t *n = spl_ast_node(sema->ast, ref); spl_symbol_t symbol = {0}; - spl_def_id_t def = 0; Assert(n != NULL); switch (n->kind) { case SPL_AST_CONTAINER_MEMBERS: { @@ -87,7 +81,7 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { n->resolved_def_id = symbol.node; n = spl_ast_node(sema->ast, n->type_decl.type_expr); if (!n) { - SPL_FATAL(&n->dbg, "type_decl must have type_expr"); + SPL_ERROR(&n->dbg, "type_decl must have type_expr"); return; } @@ -157,7 +151,6 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { Assert(sema != NULL); spl_ast_node_t *n = spl_ast_node(sema->ast, ref); spl_symbol_t symbol = {0}; - spl_def_id_t def = 0; Assert(n != NULL); switch (n->kind) { case SPL_AST_NONE: @@ -181,9 +174,10 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { sema->scope->current_scope = scope_id; vec_for(n->fn_decl.param_list, i) { spl_ast_node_ref_t ref = vec_at(n->fn_decl.param_list, i); - // sema_parse(sema, ref); + sema_parse(sema, ref); + def = spl_type_def(sema->type, n->resolved_def_id); spl_ast_node_t *node = spl_ast_node(sema->ast, ref); - Assert(node->kind = SPL_AST_PARAM_DECL); + Assert(node->kind == SPL_AST_PARAM_DECL); spl_var_def_t var_def = {0}; var_def.name = node->param_decl.name; @@ -192,11 +186,15 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { } vec_for(n->fn_decl.block, i) { sema_parse(sema, vec_at(n->fn_decl.block, i)); } sema->scope->current_scope = old_id; + + // spl_type_def_fn_build(sema->type, n->resolved_def_id, ) } break; - case SPL_AST_TYPE_DECL: - TODO(); - break; - case SPL_AST_VAR_DECL: { + case SPL_AST_TYPE_DECL: { + if (n->type_decl.type_expr) + sema_parse(sema, n->type_decl.type_expr); + } break; + case SPL_AST_VAR_DECL: + case SPL_AST_CONST_DECL: { if (n->resolved_def_id == 0) { symbol.name = n->var_const_decl.name; symbol.kind = SPL_SYMBOL_KIND_VAR; @@ -207,37 +205,106 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { def->kind = SPL_DEF_VAR; spl_scope_insert(sema->scope, sema->scope->current_scope, symbol); } - spl_def_node_t *def_node = spl_type_def(sema->type, n->resolved_def_id); + if (n->var_const_decl.type_expr) + sema_parse(sema, n->var_const_decl.type_expr); + if (n->var_const_decl.expr) + sema_parse(sema, n->var_const_decl.expr); + } break; + case SPL_AST_MEMBER_DECL: { + if (n->member_decl.type_expr) + sema_parse(sema, n->member_decl.type_expr); } break; - case SPL_AST_CONST_DECL: - case SPL_AST_MEMBER_DECL: - TODO(); - break; case SPL_AST__COMPTIME_STMT: case SPL_AST__DIRECTIVE_BLOCK: - case SPL_AST_PARAM_DECL: break; + case SPL_AST_PARAM_DECL: { + if (n->resolved_def_id == 0) { + symbol.name = n->param_decl.name; + symbol.kind = SPL_SYMBOL_KIND_VAR; + symbol.node = spl_type_def_alloc(sema->type); + n->resolved_def_id = symbol.node; + + spl_def_node_t *def = spl_type_def(sema->type, symbol.node); + def->kind = SPL_DEF_VAR; + spl_scope_insert(sema->scope, sema->scope->current_scope, symbol); + } + if (n->param_decl.type_expr) + sema_parse(sema, n->param_decl.type_expr); + } break; case SPL_AST_ATTR_ITEM: - case SPL_AST_ARGG_INIT_ITEM: - case SPL_AST_IF_STATEMENT: - case SPL_AST_IFVAR_STATEMENT: - case SPL_AST_WHILE_STATEMENT: - case SPL_AST_LOOP_STATEMENT: - case SPL_AST_FOR_STATEMENT: - case SPL_AST_MATCH_STATEMENT: - TODO(); + vec_for(n->attr_item.expr_list, i) { sema_parse(sema, vec_at(n->attr_item.expr_list, i)); } break; + case SPL_AST_ARGG_INIT_ITEM: { + if (n->aggregate_init_item.expr) + sema_parse(sema, n->aggregate_init_item.expr); + } break; + case SPL_AST_IF_STATEMENT: { + if (n->if_statement.expr) + sema_parse(sema, n->if_statement.expr); + vec_for(n->if_statement.if_block, i) { + sema_parse(sema, vec_at(n->if_statement.if_block, i)); + } + vec_for(n->if_statement.else_block, i) { + sema_parse(sema, vec_at(n->if_statement.else_block, i)); + } + } break; + case SPL_AST_IFVAR_STATEMENT: { + if (n->ifvar_statement.packed_expr) + sema_parse(sema, n->ifvar_statement.packed_expr); + vec_for(n->ifvar_statement.if_block, i) { + sema_parse(sema, vec_at(n->ifvar_statement.if_block, i)); + } + vec_for(n->ifvar_statement.else_block, i) { + sema_parse(sema, vec_at(n->ifvar_statement.else_block, i)); + } + } break; + case SPL_AST_WHILE_STATEMENT: { + if (n->while_statement.expr) + sema_parse(sema, n->while_statement.expr); + vec_for(n->while_statement.while_block, i) { + sema_parse(sema, vec_at(n->while_statement.while_block, i)); + } + } break; + case SPL_AST_LOOP_STATEMENT: { + vec_for(n->loop_statement.loop_block, i) { + sema_parse(sema, vec_at(n->loop_statement.loop_block, i)); + } + } break; + case SPL_AST_FOR_STATEMENT: { + vec_for(n->for_statement.expr_vec, i) { + sema_parse(sema, vec_at(n->for_statement.expr_vec, i)); + } + vec_for(n->for_statement.block, i) { sema_parse(sema, vec_at(n->for_statement.block, i)); } + } break; + case SPL_AST_MATCH_STATEMENT: { + if (n->match_statement.expr) + sema_parse(sema, n->match_statement.expr); + vec_for(n->match_statement.paced_exprs, i) { + sema_parse(sema, vec_at(n->match_statement.paced_exprs, i)); + } + vec_for(n->match_statement.match_block, i) { + sema_parse(sema, vec_at(n->match_statement.match_block, i)); + } + } break; case SPL_AST_RET_STATEMENT: { sema_parse(sema, n->ret_statement.expr); } break; case SPL_AST_BREAK_STATEMENT: case SPL_AST_CONTINUE_STATEMENT: - case SPL_AST_DEFER_STATEMENT: + case SPL_AST_DEFER_STATEMENT: { + vec_for(n->defer_statement.block_or_statement, i) { + sema_parse(sema, vec_at(n->defer_statement.block_or_statement, i)); + } + } break; case SPL_AST_TRY_STATEMENT: case SPL_AST_CATCH_STATEMENT: case SPL_AST_ERRDEFER_STATEMEMT: case SPL_AST_EXPR_STATEMENT: - case SPL_AST_PACKED_EXPR: + break; + case SPL_AST_PACKED_EXPR: { + if (n->packed_expr.expr) + sema_parse(sema, n->packed_expr.expr); + } break; case SPL_AST_ASSIGN_EXPR: case SPL_AST_ASSIGN_ADD_EXPR: case SPL_AST_ASSIGN_SUB_EXPR: @@ -268,17 +335,49 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { case SPL_AST_MUL_EXPR: case SPL_AST_DIV_EXPR: case SPL_AST_MOD_EXPR: + if (n->op_expr.left) + sema_parse(sema, n->op_expr.left); + if (n->op_expr.right) + sema_parse(sema, n->op_expr.right); + break; case SPL_AST_MINUS_EXPR: case SPL_AST_NOT_EXPR: case SPL_AST_BIT_NOT_EXPR: case SPL_AST_ADDRESS_EXPR: + if (n->prefix_expr.postfix_expr) + sema_parse(sema, n->prefix_expr.postfix_expr); + break; case SPL_AST_CALL_EXPR: + if (n->postfix_expr.primary_expr) + sema_parse(sema, n->postfix_expr.primary_expr); + vec_for(n->postfix_expr.call_expr, i) { + sema_parse(sema, vec_at(n->postfix_expr.call_expr, i)); + } + break; case SPL_AST_FIELD_EXPR: case SPL_AST_DEREF_EXPR: + if (n->postfix_expr.primary_expr) + sema_parse(sema, n->postfix_expr.primary_expr); + break; case SPL_AST_INDEX_EXPR: + if (n->postfix_expr.primary_expr) + sema_parse(sema, n->postfix_expr.primary_expr); + if (n->postfix_expr.index_expr) + sema_parse(sema, n->postfix_expr.index_expr); + break; case SPL_AST_SLICE_EXPR: + if (n->postfix_expr.primary_expr) + sema_parse(sema, n->postfix_expr.primary_expr); + if (n->postfix_expr.slice_expr.begin) + sema_parse(sema, n->postfix_expr.slice_expr.begin); + if (n->postfix_expr.slice_expr.end) + sema_parse(sema, n->postfix_expr.slice_expr.end); + break; case SPL_AST_AS_EXPR: - TODO(); + if (n->postfix_expr.primary_expr) + sema_parse(sema, n->postfix_expr.primary_expr); + if (n->postfix_expr.type_expr) + sema_parse(sema, n->postfix_expr.type_expr); break; case SPL_AST_EXPR_INTEGER_LIT: case SPL_AST_EXPR_FLOAT_LIT: @@ -291,28 +390,75 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { break; case SPL_AST_EXPR_IDENT: { if (!spl_scope_find(sema->scope, n->primary_expr.ident, &symbol)) { - LOG_FATAL("can't find ident `%s`", n->primary_expr.ident); + SPL_ERROR(&n->dbg, "can't find ident `%s`", n->primary_expr.ident); return; } Assert(symbol.node != 0); n->resolved_def_id = symbol.node; } break; case SPL_AST_ARGGREGATE_INIT: + vec_for(n->primary_expr.aggregate_init.expr, i) { + sema_parse(sema, vec_at(n->primary_expr.aggregate_init.expr, i)); + } + break; case SPL_AST_EXPR_EXPR: + if (n->primary_expr.expr) + sema_parse(sema, n->primary_expr.expr); + break; case SPL_AST_ARRAY_LIT: + if (n->primary_expr.array_lit_expr.type_expr) + sema_parse(sema, n->primary_expr.array_lit_expr.type_expr); + vec_for(n->primary_expr.array_lit_expr.expr_list, i) { + sema_parse(sema, vec_at(n->primary_expr.array_lit_expr.expr_list, i)); + } + break; case SPL_AST_BUILTIN_EXPR: + vec_for(n->primary_expr.builtin_expr.expr_list, i) { + sema_parse(sema, vec_at(n->primary_expr.builtin_expr.expr_list, i)); + } + break; case SPL_AST_BLOCK_EXPR: + vec_for(n->primary_expr.block_expr, i) { + sema_parse(sema, vec_at(n->primary_expr.block_expr, i)); + } + break; case SPL_AST_BASE_TYPE_FN: + vec_for(n->type_expr.attr_list, i) { sema_parse(sema, vec_at(n->type_expr.attr_list, i)); } + vec_for(n->type_expr.fn_type.param_list, i) { + sema_parse(sema, vec_at(n->type_expr.fn_type.param_list, i)); + } + if (n->type_expr.fn_type.type_expr) + sema_parse(sema, n->type_expr.fn_type.type_expr); + break; case SPL_AST_BASE_TYPE_PATH: - TODO(); + vec_for(n->type_expr.attr_list, i) { sema_parse(sema, vec_at(n->type_expr.attr_list, i)); } break; case SPL_AST_TYPE_POINTER: + vec_for(n->type_expr.attr_list, i) { sema_parse(sema, vec_at(n->type_expr.attr_list, i)); } + if (n->type_expr.pointer_type.pointee) + sema_parse(sema, n->type_expr.pointer_type.pointee); + break; case SPL_AST_TYPE_ARRAY: + vec_for(n->type_expr.attr_list, i) { sema_parse(sema, vec_at(n->type_expr.attr_list, i)); } + if (n->type_expr.array_type.element) + sema_parse(sema, n->type_expr.array_type.element); + if (n->type_expr.array_type.size) + sema_parse(sema, n->type_expr.array_type.size); + break; case SPL_AST_TYPE_SLICE: + vec_for(n->type_expr.attr_list, i) { sema_parse(sema, vec_at(n->type_expr.attr_list, i)); } + if (n->type_expr.slice_type.element) + sema_parse(sema, n->type_expr.slice_type.element); + break; case SPL_AST_TYPE_STRUCT: case SPL_AST_TYPE_UNION: case SPL_AST_TYPE_SHAPE: case SPL_AST_TYPE_ENUM: + vec_for(n->type_expr.attr_list, i) { sema_parse(sema, vec_at(n->type_expr.attr_list, i)); } + vec_for(n->type_expr.aggregate_list, i) { + sema_parse(sema, vec_at(n->type_expr.aggregate_list, i)); + } + break; case SPL_AST_TYPE_VOID: case SPL_AST_TYPE_BOOL: case SPL_AST_TYPE_OPAQUE: @@ -330,7 +476,6 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { case SPL_AST_TYPE__F64: case SPL_AST_TYPE_ANY: case SPL_AST_TYPE_IDENT: - TODO(); break; case SPL_AST_COUNT: UNREACHABLE(); diff --git a/stage1/spl_type.c b/stage1/spl_type.c index b3a3686..693f0a7 100644 --- a/stage1/spl_type.c +++ b/stage1/spl_type.c @@ -1,6 +1,52 @@ #include "spl_type.h" -static usize spl_type_hash(spl_type_node_t n) { return n.kind; } +static usize spl_type_hash(spl_type_node_t n) { + usize hash = n.kind << 20; + switch (n.kind) { + case SPL_TYPE_ERROR: + case SPL_TYPE_VOID: + case SPL_TYPE_BOOL: + break; + case SPL_TYPE_INT: + hash += n.int_type.bits + n.int_type.is_signed; + break; + case SPL_TYPE_FLOAT: + hash += n.float_type.bits; + break; + case SPL_TYPE_PTR: + hash += n.ptr_pointee; + break; + case SPL_TYPE_SLICE: + hash += n.slice_element; + break; + case SPL_TYPE_RANGE: + hash += n.range_element; + break; + case SPL_TYPE_ARRAY: + hash += n.array_type.element + n.array_type.len; + break; + case SPL_TYPE_STRUCT: + case SPL_TYPE_UNION: + hash += n.layout.mode; + hash += n.layout.fixed_align_bits; + vec_for(n.agg_field_types, i) { hash += vec_at(n.agg_field_types, i); } + break; + case SPL_TYPE_ENUM: + hash += n.layout.mode; + hash += n.layout.fixed_align_bits; + hash += n.adt_type.tag_type; + vec_for(n.adt_type.variants, i) { hash += vec_at(n.adt_type.variants, i); } + break; + case SPL_TYPE_FN: + hash += n.fn_type.ret; + vec_for(n.fn_type.params, i) { hash += vec_at(n.fn_type.params, i); } + break; + default: // TODO + break; + } + return hash; +} + static int spl_type_eq(spl_type_node_t n1, spl_type_node_t n2) { if (n1.kind != n2.kind) return 1; @@ -37,8 +83,42 @@ static int spl_type_eq(spl_type_node_t n1, spl_type_node_t n2) { if (n1.array_type.len != n2.array_type.len) return 1; break; - // TODO - default: + case SPL_TYPE_STRUCT: + case SPL_TYPE_UNION: + if (n1.layout.mode != n2.layout.mode || + n1.layout.fixed_align_bits != n2.layout.fixed_align_bits) + return 1; + if (vec_size(n1.agg_field_types) != vec_size(n2.agg_field_types)) + return 1; + vec_for(n1.agg_field_types, i) { + if (vec_at(n1.agg_field_types, i) != vec_at(n2.agg_field_types, i)) + return 1; + } + break; + case SPL_TYPE_ENUM: + if (n1.layout.mode != n2.layout.mode || + n1.layout.fixed_align_bits != n2.layout.fixed_align_bits) + return 1; + if (n1.adt_type.tag_type != n2.adt_type.tag_type) + return 1; + if (vec_size(n1.adt_type.variants) != vec_size(n2.adt_type.variants)) + return 1; + vec_for(n1.adt_type.variants, i) { + if (vec_at(n1.adt_type.variants, i) != vec_at(n2.adt_type.variants, i)) + return 1; + } + break; + case SPL_TYPE_FN: + if (n1.fn_type.ret != n2.fn_type.ret) + return 1; + if (vec_size(n1.fn_type.params) != vec_size(n2.fn_type.params)) + return 1; + vec_for(n1.fn_type.params, i) { + if (vec_at(n1.fn_type.params, i) != vec_at(n2.fn_type.params, i)) + return 1; + } + break; + default: // TODO return 1; } return 0; @@ -60,6 +140,65 @@ spl_type_id_t spl_type_def_alloc(spl_type_t *type) { return vec_size(type->def_table) - 1; } +spl_type_id_t spl_type_def_agg_build(spl_type_t *type, spl_def_id_t def, spl_type_node_kind_t tk, + spl_type_id_t tag_type, spl_type_layout_t layout) { + if (tk != SPL_TYPE_STRUCT && tk != SPL_TYPE_UNION && tk != SPL_TYPE_ENUM) { + return 0; + } + spl_def_node_t *d = spl_type_def(type, def); + if (!d) { + return 0; + } + spl_type_node_t tn = {0}; + tn.kind = tk; + tn.layout = layout; + if (tk == SPL_TYPE_ENUM) { + vec_init(tn.adt_type.variants); + tn.adt_type.tag_type = tag_type; + } else { + vec_init(tn.agg_field_types); + } + vec_for(d->agg_def, i) { + if (tk == SPL_TYPE_ENUM) { + vec_push(tn.adt_type.variants, vec_at(d->agg_def, i).type_id); + } else { + vec_push(tn.agg_field_types, vec_at(d->agg_def, i).type_id); + } + } + usize old = vec_size(type->type_table); + spl_type_id_t tid = spl_type_node_push(type, tn); + if (tid < old) { + if (tk == SPL_TYPE_ENUM) { + vec_free(tn.adt_type.variants); + } else { + vec_free(tn.agg_field_types); + } + } + d->type_id = tid; + return tid; +} + +spl_type_id_t spl_type_def_fn_build(spl_type_t *type, spl_def_id_t def, spl_type_id_t ret) { + spl_def_node_t *d = spl_type_def(type, def); + if (!d) { + return 0; + } + spl_type_node_t tn = {0}; + tn.kind = SPL_TYPE_FN; + vec_init(tn.fn_type.params); + vec_for(d->fn_params_def, i) { + vec_push(tn.fn_type.params, vec_at(d->fn_params_def, i).type_id); + } + tn.fn_type.ret = ret; + usize old = vec_size(type->type_table); + spl_type_id_t tid = spl_type_node_push(type, tn); + if (tid < old) { + vec_free(tn.fn_type.params); + } + d->type_id = tid; + return tid; +} + void spl_type_init(spl_type_t *type) { vec_init(type->type_table); vec_push(type->type_table, (spl_type_node_t){0}); @@ -166,7 +305,7 @@ spl_def_node_t *spl_type_def(spl_type_t *type, spl_def_id_t id) { void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id) { spl_type_node_t *n = spl_type_node(type, id); if (!n) { - printf("(err)"); + printf("none"); return; } switch (n->kind) { @@ -231,7 +370,7 @@ void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id) { void spl_type_def_dump(spl_type_t *type, spl_def_id_t id) { spl_def_node_t *node = spl_type_def(type, id); if (!node) { - printf("(err)"); + printf("none"); return; } diff --git a/stage1/spl_type.h b/stage1/spl_type.h index 5bd8fd5..2154494 100644 --- a/stage1/spl_type.h +++ b/stage1/spl_type.h @@ -9,27 +9,37 @@ typedef VEC(spl_type_id_t) spl_type_id_vec_t; typedef usize spl_def_id_t; /* 0 is error */ typedef VEC(spl_def_id_t) spl_def_id_vec_t; +typedef enum { + SPL_TYPE_ERROR, + SPL_TYPE_VOID, + SPL_TYPE_BOOL, + SPL_TYPE_INT, + SPL_TYPE_FLOAT, + SPL_TYPE_PTR, + SPL_TYPE_SLICE, // 未来拥有泛型后删除 + SPL_TYPE_RANGE, // 未来拥有泛型后删除 + SPL_TYPE_ARRAY, + SPL_TYPE_STRUCT, + SPL_TYPE_UNION, + SPL_TYPE_ENUM, + SPL_TYPE_FN, + SPL_TYPE_ID, +} spl_type_node_kind_t; + +typedef enum { + SPL_TYPE_LAYOUT_AUTO, + SPL_TYPE_LAYOUT_EXTERN_C, + SPL_TYPE_LAYOUT_PACKED, +} spl_type_layout_mode_t; + typedef struct { - enum { - SPL_TYPE_ERROR, - SPL_TYPE_VOID, - SPL_TYPE_BOOL, - SPL_TYPE_INT, - SPL_TYPE_FLOAT, - SPL_TYPE_PTR, - SPL_TYPE_SLICE, // 未来拥有泛型后删除 - SPL_TYPE_RANGE, // 未来拥有泛型后删除 - SPL_TYPE_ARRAY, - SPL_TYPE_STRUCT, - SPL_TYPE_UNION, - SPL_TYPE_ENUM, - SPL_TYPE_FN, - SPL_TYPE_ID, - } kind; - struct { - enum { AUTO, EXTERN_C, PACKED } mode; - usize fixed_align_bits; - } layout; + spl_type_layout_mode_t mode; + usize fixed_align_bits; +} spl_type_layout_t; + +typedef struct { + spl_type_node_kind_t kind; + spl_type_layout_t layout; union { struct { usize bits; @@ -109,4 +119,8 @@ spl_def_node_t *spl_type_def(spl_type_t *type, spl_def_id_t id); spl_type_id_t spl_type_def_alloc(spl_type_t *type); spl_type_id_t spl_type_node_push(spl_type_t *type, spl_type_node_t type_node); +spl_type_id_t spl_type_def_agg_build(spl_type_t *type, spl_def_id_t def, spl_type_node_kind_t tk, + spl_type_id_t tag_type, spl_type_layout_t layout); +spl_type_id_t spl_type_def_fn_build(spl_type_t *type, spl_def_id_t def, spl_type_id_t ret); + #endif /* __SPL_TYPE_H__ */