537 lines
19 KiB
C
537 lines
19 KiB
C
#include "spl_sema.h"
|
|
|
|
void spl_scope_init(spl_scope_t *scope) {
|
|
vec_init(scope->scopes);
|
|
vec_push(scope->scopes, (spl_scope_node_t){0});
|
|
scope->current_scope = 0;
|
|
scope->root_scope = 0;
|
|
}
|
|
|
|
void spl_scope_drop(spl_scope_t *scope) {
|
|
vec_free(scope->scopes);
|
|
scope->current_scope = 0;
|
|
scope->root_scope = 0;
|
|
}
|
|
|
|
spl_scope_id_t spl_scope_alloc(spl_scope_t *scope) {
|
|
spl_scope_node_t n;
|
|
n.parent = scope->current_scope;
|
|
map_init(n.symbols, MAP_HASH_STR, MAP_CMP_STR);
|
|
vec_push(scope->scopes, n);
|
|
return vec_size(scope->scopes) - 1;
|
|
}
|
|
|
|
bool spl_scope_insert(spl_scope_t *scope, spl_scope_id_t id, spl_symbol_t symbol) {
|
|
if (!id || id >= vec_size(scope->scopes)) {
|
|
LOG_FATAL("sema scope insert error");
|
|
return false;
|
|
}
|
|
spl_symbol_t old = {0};
|
|
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
|
|
SPL_ERROR(&(spl_dbg_node_t){0}, "find same symbol %s", symbol.name);
|
|
return false;
|
|
}
|
|
map_put(node->symbols, symbol.name, symbol);
|
|
return true;
|
|
}
|
|
|
|
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_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);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Parse once
|
|
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};
|
|
Assert(n != NULL);
|
|
switch (n->kind) {
|
|
case SPL_AST_CONTAINER_MEMBERS: {
|
|
symbol.name = "$file";
|
|
symbol.kind = SPL_SYMBOL_KIND_TYPE;
|
|
symbol.node = spl_type_def_alloc(sema->type);
|
|
n->resolved_def_id = symbol.node;
|
|
|
|
spl_scope_id_t scope_id = spl_scope_alloc(sema->scope);
|
|
sema->scope->current_scope = scope_id;
|
|
sema->scope->root_scope = scope_id;
|
|
spl_scope_insert(sema->scope, scope_id, symbol);
|
|
vec_for(n->container_members, i) { sema_collect(sema, vec_at(n->container_members, i)); }
|
|
|
|
spl_def_node_t *def = spl_type_def(sema->type, symbol.node);
|
|
def->kind = SPL_DEF_AGG;
|
|
break;
|
|
}
|
|
case SPL_AST_TYPE_DECL: {
|
|
symbol.name = n->type_decl.name;
|
|
symbol.kind = SPL_SYMBOL_KIND_TYPE;
|
|
symbol.node = spl_type_def_alloc(sema->type);
|
|
n->resolved_def_id = symbol.node;
|
|
n = spl_ast_node(sema->ast, n->type_decl.type_expr);
|
|
if (!n) {
|
|
SPL_ERROR(&n->dbg, "type_decl must have type_expr");
|
|
return;
|
|
}
|
|
|
|
spl_def_node_t *def = spl_type_def(sema->type, symbol.node);
|
|
switch (n->kind) {
|
|
case SPL_AST_TYPE_STRUCT:
|
|
case SPL_AST_TYPE_UNION:
|
|
case SPL_AST_TYPE_ENUM:
|
|
case SPL_AST_TYPE_SHAPE: /* TODO for shape */
|
|
def->kind = SPL_DEF_AGG;
|
|
spl_scope_id_t scope_id = spl_scope_alloc(sema->scope);
|
|
spl_scope_id_t old_id = sema->scope->current_scope;
|
|
spl_scope_insert(sema->scope, old_id, symbol);
|
|
sema->scope->current_scope = scope_id;
|
|
vec_for(n->type_expr.aggregate_list, i) {
|
|
sema_collect(sema, vec_at(n->type_expr.aggregate_list, i));
|
|
}
|
|
sema->scope->current_scope = old_id;
|
|
break;
|
|
default:
|
|
def->kind = SPL_DEF_SCALAR;
|
|
break;
|
|
}
|
|
spl_scope_insert(sema->scope, sema->scope->current_scope, symbol);
|
|
} break;
|
|
case SPL_AST_FN_DECL:
|
|
case SPL_AST_FN_DEFINE: {
|
|
symbol.name = n->fn_decl.name;
|
|
symbol.kind = SPL_SYMBOL_KIND_FN;
|
|
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_FN_PARAMS;
|
|
spl_scope_insert(sema->scope, sema->scope->current_scope, symbol);
|
|
} break;
|
|
case SPL_AST_VAR_DECL:
|
|
case SPL_AST_CONST_DECL: {
|
|
symbol.name = n->var_const_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);
|
|
} break;
|
|
case SPL_AST_MEMBER_DECL: {
|
|
symbol.name = n->member_decl.name;
|
|
symbol.kind = SPL_SYMBOL_KIND_MEMBER;
|
|
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_MEMBER;
|
|
spl_scope_insert(sema->scope, sema->scope->current_scope, symbol);
|
|
} break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Parse twice
|
|
static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
if (ref == 0)
|
|
return;
|
|
Assert(sema != NULL);
|
|
spl_ast_node_t *n = spl_ast_node(sema->ast, ref);
|
|
spl_symbol_t symbol = {0};
|
|
Assert(n != NULL);
|
|
switch (n->kind) {
|
|
case SPL_AST_NONE:
|
|
UNREACHABLE();
|
|
break;
|
|
case SPL_AST_CONTAINER_MEMBERS: {
|
|
vec_for(n->container_members, i) { sema_parse(sema, vec_at(n->container_members, i)); }
|
|
} break;
|
|
case SPL_AST_FN_DECL:
|
|
case SPL_AST_FN_DEFINE: {
|
|
if (n->resolved_def_id == 0) {
|
|
Panic("fn `%s` don't collect", n->fn_decl.name);
|
|
}
|
|
|
|
spl_def_node_t *def = spl_type_def(sema->type, n->resolved_def_id);
|
|
def->kind = SPL_DEF_FN_PARAMS;
|
|
vec_init(def->fn_params_def);
|
|
|
|
spl_scope_id_t scope_id = spl_scope_alloc(sema->scope);
|
|
spl_scope_id_t old_id = sema->scope->current_scope;
|
|
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);
|
|
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);
|
|
|
|
spl_var_def_t var_def = {0};
|
|
var_def.name = node->param_decl.name;
|
|
var_def.scope_id = sema->scope->current_scope;
|
|
vec_push(def->fn_params_def, var_def);
|
|
}
|
|
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: {
|
|
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;
|
|
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->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__COMPTIME_STMT:
|
|
case SPL_AST__DIRECTIVE_BLOCK:
|
|
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:
|
|
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: {
|
|
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:
|
|
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:
|
|
case SPL_AST_ASSIGN_MUL_EXPR:
|
|
case SPL_AST_ASSIGN_DIV_EXPR:
|
|
case SPL_AST_ASSIGN_MOD_EXPR:
|
|
case SPL_AST_ASSIGN_AND_EXPR:
|
|
case SPL_AST_ASSIGN_OR_EXPR:
|
|
case SPL_AST_ASSIGN_XOR_EXPR:
|
|
case SPL_AST_ASSIGN_LSHIFT_EXPR:
|
|
case SPL_AST_ASSIGN_USHIFT_EXPR:
|
|
case SPL_AST_BOOL_OR_EXPR:
|
|
case SPL_AST_BOOL_AND_EXPR:
|
|
case SPL_AST_BIT_OR_EXPR:
|
|
case SPL_AST_BIT_XOR_EXPR:
|
|
case SPL_AST_BIT_AND_EXPR:
|
|
case SPL_AST_CMP_EQ_EXPR:
|
|
case SPL_AST_CMP_NE_EXPR:
|
|
case SPL_AST_CMP_LE_EXPR:
|
|
case SPL_AST_CMP_GE_EXPR:
|
|
case SPL_AST_CMP_LT_EXPR:
|
|
case SPL_AST_CMP_GT_EXPR:
|
|
case SPL_AST_RANGE_EXPR:
|
|
case SPL_AST_LSHIFT_EXPR:
|
|
case SPL_AST_RSHIFT_EXPR:
|
|
case SPL_AST_ADD_EXPR:
|
|
case SPL_AST_SUB_EXPR:
|
|
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:
|
|
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:
|
|
case SPL_AST_EXPR_CHAR_LIT:
|
|
case SPL_AST_EXPR_STRING_LIT:
|
|
case SPL_AST_EXPR_TRUE:
|
|
case SPL_AST_EXPR_FALSE:
|
|
case SPL_AST_EXPR_NULL:
|
|
case SPL_AST_EXPR_UNDEFINED:
|
|
break;
|
|
case SPL_AST_EXPR_IDENT: {
|
|
if (!spl_scope_find(sema->scope, n->primary_expr.ident, &symbol)) {
|
|
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:
|
|
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:
|
|
case SPL_AST_TYPE_I8:
|
|
case SPL_AST_TYPE_U8:
|
|
case SPL_AST_TYPE_I16:
|
|
case SPL_AST_TYPE_U16:
|
|
case SPL_AST_TYPE_I32:
|
|
case SPL_AST_TYPE_U32:
|
|
case SPL_AST_TYPE_I64:
|
|
case SPL_AST_TYPE_U64:
|
|
case SPL_AST_TYPE_ISIZE:
|
|
case SPL_AST_TYPE_USIZE:
|
|
case SPL_AST_TYPE__F32:
|
|
case SPL_AST_TYPE__F64:
|
|
case SPL_AST_TYPE_ANY:
|
|
case SPL_AST_TYPE_IDENT:
|
|
break;
|
|
case SPL_AST_COUNT:
|
|
UNREACHABLE();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void spl_sema_init(spl_sema_t *sema, spl_ast_t *ast, spl_type_t *type, spl_scope_t *scope) {
|
|
Assert(sema && ast && type && scope);
|
|
sema->ast = ast;
|
|
sema->type = type;
|
|
sema->scope = scope;
|
|
sema->error_count = 0;
|
|
sema->root = (spl_symbol_t){0};
|
|
}
|
|
|
|
void spl_sema_drop(spl_sema_t *sema) { (void)sema; }
|
|
|
|
void spl_sema_run(spl_sema_t *sema) {
|
|
if (!sema->ast || !sema->ast->root)
|
|
return;
|
|
|
|
spl_ast_node_t *ast_node = spl_ast_node(sema->ast, sema->ast->root);
|
|
Assert(ast_node != NULL && ast_node->kind == SPL_AST_CONTAINER_MEMBERS);
|
|
|
|
// 第一趟 实现顺序无关地相互引用
|
|
sema_collect(sema, sema->ast->root);
|
|
|
|
// 第二趟 正式解析
|
|
sema_parse(sema, sema->ast->root);
|
|
}
|
|
|
|
void spl_sema_dump(spl_sema_t *sema) {
|
|
printf("Scopes:\n");
|
|
vec_for(sema->scope->scopes, i) {
|
|
if (i == 0)
|
|
continue;
|
|
spl_scope_node_t scope = vec_at(sema->scope->scopes, i);
|
|
printf("scope[%zu] parent=%zu\n", i, scope.parent);
|
|
map_for(scope.symbols, j) {
|
|
spl_symbol_t *symbol = &unsafe_map_at(scope.symbols, j).val;
|
|
printf(" %s -> def`%s`#%zu\n", unsafe_map_at(scope.symbols, j).key, symbol->name,
|
|
symbol->node);
|
|
}
|
|
}
|
|
printf("TypeTable:\n");
|
|
vec_for(sema->type->type_table, i) {
|
|
printf(" id#%zu type=", i);
|
|
spl_type_pure_dump(sema->type, i);
|
|
printf("\n");
|
|
}
|
|
printf("DefTable:\n");
|
|
vec_for(sema->type->def_table, i) {
|
|
printf(" def#%zu ", i);
|
|
spl_type_def_dump(sema->type, i);
|
|
printf("\n");
|
|
}
|
|
}
|