|
|
|
|
@@ -82,6 +82,7 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
n = spl_ast_node(sema->ast, n->type_decl.type_expr);
|
|
|
|
|
if (!n) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "type_decl must have type_expr");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -103,9 +104,9 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
def->kind = SPL_DEF_SCALAR;
|
|
|
|
|
spl_scope_insert(sema->scope, sema->scope->current_scope, symbol);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
spl_scope_insert(sema->scope, sema->scope->current_scope, symbol);
|
|
|
|
|
} break;
|
|
|
|
|
case SPL_AST_FN_DECL:
|
|
|
|
|
case SPL_AST_FN_DEFINE: {
|
|
|
|
|
@@ -145,12 +146,136 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse twice
|
|
|
|
|
static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
if (ref == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// use for assign_expr as_expr
|
|
|
|
|
static spl_type_id_t sema_coerce(spl_sema_t *sema, spl_type_id_t to, spl_type_id_t from) {
|
|
|
|
|
// var := from
|
|
|
|
|
if (to == 0) {
|
|
|
|
|
return from;
|
|
|
|
|
}
|
|
|
|
|
// error
|
|
|
|
|
if (from == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// same
|
|
|
|
|
if (to == from) {
|
|
|
|
|
return to;
|
|
|
|
|
}
|
|
|
|
|
spl_type_node_t *tn = spl_type_node(sema->type, to);
|
|
|
|
|
spl_type_node_t *fn = spl_type_node(sema->type, from);
|
|
|
|
|
Assert(tn != NULL && fn != NULL);
|
|
|
|
|
switch (fn->kind) {
|
|
|
|
|
case SPL_TYPE_UNDEFINED:
|
|
|
|
|
return to;
|
|
|
|
|
case SPL_TYPE_NULL:
|
|
|
|
|
if (tn->kind == SPL_TYPE_PTR || tn->kind == SPL_TYPE_SLICE) {
|
|
|
|
|
return to;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SPL_TYPE_INT:
|
|
|
|
|
if (tn->kind != SPL_TYPE_INT) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// var = comptime_int
|
|
|
|
|
if (tn->int_type.bits > 0 && fn->int_type.bits == 0) {
|
|
|
|
|
return to;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// not same signed
|
|
|
|
|
if (tn->int_type.is_signed != fn->int_type.is_signed) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// var i32 = i32/i16
|
|
|
|
|
if (tn->int_type.bits >= fn->int_type.bits) {
|
|
|
|
|
return to;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SPL_TYPE_FLOAT:
|
|
|
|
|
// TODO
|
|
|
|
|
break;
|
|
|
|
|
case SPL_TYPE_ARRAY:
|
|
|
|
|
// TODO
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// use for op_expr
|
|
|
|
|
static spl_type_id_t sema_coerce_balance(spl_sema_t *sema, spl_type_id_t t1, spl_type_id_t t2) {
|
|
|
|
|
// error
|
|
|
|
|
if (t1 == 0 || t2 == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// same
|
|
|
|
|
if (t1 == t2) {
|
|
|
|
|
return t1;
|
|
|
|
|
}
|
|
|
|
|
spl_type_node_t *n1 = spl_type_node(sema->type, t1);
|
|
|
|
|
spl_type_node_t *n2 = spl_type_node(sema->type, t2);
|
|
|
|
|
Assert(n1 != NULL && n2 != NULL);
|
|
|
|
|
|
|
|
|
|
// TODO 应该推导类型
|
|
|
|
|
if (n1->kind == SPL_TYPE_UNDEFINED && n1->kind == SPL_TYPE_UNDEFINED) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (n1->kind == SPL_TYPE_UNDEFINED) {
|
|
|
|
|
return t2;
|
|
|
|
|
}
|
|
|
|
|
if (n2->kind == SPL_TYPE_UNDEFINED) {
|
|
|
|
|
return t1;
|
|
|
|
|
}
|
|
|
|
|
if (n1->kind == SPL_TYPE_NULL) {
|
|
|
|
|
return (n2->kind == SPL_TYPE_PTR || n2->kind == SPL_TYPE_SLICE) ? t2 : 0;
|
|
|
|
|
}
|
|
|
|
|
if (n2->kind == SPL_TYPE_NULL) {
|
|
|
|
|
return (n1->kind == SPL_TYPE_PTR || n1->kind == SPL_TYPE_SLICE) ? t1 : 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (n1->kind != n2->kind) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (n1->kind) {
|
|
|
|
|
case SPL_TYPE_INT:
|
|
|
|
|
if (n1->int_type.is_signed != n2->int_type.is_signed) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return n1->int_type.bits >= n2->int_type.bits ? t1 : t2;
|
|
|
|
|
case SPL_TYPE_FLOAT:
|
|
|
|
|
return n1->float_type.bits >= n2->float_type.bits ? t1 : t2;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool sema_coerce_for_bool(spl_sema_t *sema, spl_type_id_t from) {
|
|
|
|
|
spl_type_id_t bool_tid =
|
|
|
|
|
spl_type_node_push(sema->type, (spl_type_node_t){.kind = SPL_TYPE_BOOL});
|
|
|
|
|
return sema_coerce(sema, bool_tid, from) == bool_tid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void sema_push_scope(spl_sema_t *sema) {
|
|
|
|
|
spl_scope_id_t scope_id = spl_scope_alloc(sema->scope);
|
|
|
|
|
sema->store_scope = sema->scope->current_scope;
|
|
|
|
|
sema->scope->current_scope = scope_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void sema_pop_scope(spl_sema_t *sema) {
|
|
|
|
|
sema->scope->current_scope = sema->store_scope;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
if (ref == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
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:
|
|
|
|
|
@@ -160,42 +285,59 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
vec_for(n->container_members, i) { sema_parse(sema, vec_at(n->container_members, i)); }
|
|
|
|
|
} break;
|
|
|
|
|
case SPL_AST_FN_DECL:
|
|
|
|
|
break;
|
|
|
|
|
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);
|
|
|
|
|
sema_push_scope(sema);
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
spl_var_def_vec_t params;
|
|
|
|
|
vec_init(params);
|
|
|
|
|
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_type_id_t tid = sema_parse(sema, ref);
|
|
|
|
|
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.type_id = tid;
|
|
|
|
|
var_def.def_id = node->resolved_def_id;
|
|
|
|
|
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;
|
|
|
|
|
vec_push(params, var_def);
|
|
|
|
|
|
|
|
|
|
// spl_type_def_fn_build(sema->type, n->resolved_def_id, )
|
|
|
|
|
if (node->resolved_def_id) {
|
|
|
|
|
spl_def_node_t *pd = spl_type_def(sema->type, node->resolved_def_id);
|
|
|
|
|
Assert(pd != NULL);
|
|
|
|
|
pd->var_def.type_id = tid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
spl_def_node_t *def2 = spl_type_def(sema->type, n->resolved_def_id);
|
|
|
|
|
vec_free(def2->fn_params_def);
|
|
|
|
|
def2->fn_params_def = params;
|
|
|
|
|
|
|
|
|
|
spl_type_id_t ret_id = sema_parse(sema, n->fn_decl.type_expr);
|
|
|
|
|
spl_type_def_fn_build(sema->type, n->resolved_def_id, ret_id);
|
|
|
|
|
spl_type_id_t old_ret = sema->current_fn_ret_tid;
|
|
|
|
|
sema->current_fn_ret_tid = ret_id;
|
|
|
|
|
vec_for(n->fn_decl.block, i) { sema_parse(sema, vec_at(n->fn_decl.block, i)); }
|
|
|
|
|
sema->current_fn_ret_tid = old_ret;
|
|
|
|
|
sema_pop_scope(sema);
|
|
|
|
|
} break;
|
|
|
|
|
case SPL_AST_TYPE_DECL: {
|
|
|
|
|
if (n->type_decl.type_expr)
|
|
|
|
|
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) {
|
|
|
|
|
spl_symbol_t symbol = {0};
|
|
|
|
|
symbol.name = n->var_const_decl.name;
|
|
|
|
|
symbol.kind = SPL_SYMBOL_KIND_VAR;
|
|
|
|
|
symbol.node = spl_type_def_alloc(sema->type);
|
|
|
|
|
@@ -205,20 +347,37 @@ 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);
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
spl_def_node_t *def = spl_type_def(sema->type, n->resolved_def_id);
|
|
|
|
|
Assert(def != NULL);
|
|
|
|
|
spl_type_id_t decl_tid = 0;
|
|
|
|
|
if (n->var_const_decl.type_expr) {
|
|
|
|
|
decl_tid = sema_parse(sema, n->var_const_decl.type_expr);
|
|
|
|
|
}
|
|
|
|
|
if (n->var_const_decl.expr == 0) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "must be assign");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
spl_type_id_t et = sema_parse(sema, n->var_const_decl.expr);
|
|
|
|
|
decl_tid = sema_coerce(sema, decl_tid, et);
|
|
|
|
|
if (decl_tid == 0) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "decl type must not none %d");
|
|
|
|
|
sema->error_count += 1;
|
|
|
|
|
}
|
|
|
|
|
def->type_id = decl_tid;
|
|
|
|
|
def->var_def.type_id = decl_tid;
|
|
|
|
|
} break;
|
|
|
|
|
case SPL_AST_MEMBER_DECL: {
|
|
|
|
|
if (n->member_decl.type_expr)
|
|
|
|
|
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) {
|
|
|
|
|
spl_symbol_t symbol = {0};
|
|
|
|
|
symbol.name = n->param_decl.name;
|
|
|
|
|
symbol.kind = SPL_SYMBOL_KIND_VAR;
|
|
|
|
|
symbol.node = spl_type_def_alloc(sema->type);
|
|
|
|
|
@@ -228,19 +387,32 @@ 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);
|
|
|
|
|
}
|
|
|
|
|
if (n->param_decl.type_expr)
|
|
|
|
|
sema_parse(sema, n->param_decl.type_expr);
|
|
|
|
|
spl_type_id_t ptid = 0;
|
|
|
|
|
if (n->param_decl.type_expr) {
|
|
|
|
|
ptid = sema_parse(sema, n->param_decl.type_expr);
|
|
|
|
|
}
|
|
|
|
|
spl_def_node_t *pd = spl_type_def(sema->type, n->resolved_def_id);
|
|
|
|
|
pd->var_def.type_id = ptid;
|
|
|
|
|
return ptid;
|
|
|
|
|
} 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)
|
|
|
|
|
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);
|
|
|
|
|
if (!n->if_statement.expr) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "if statement not have condition expr");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
spl_type_id_t ct = sema_parse(sema, n->if_statement.expr);
|
|
|
|
|
if (!sema_coerce_for_bool(sema, ct)) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "if condition must be bool");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
}
|
|
|
|
|
vec_for(n->if_statement.if_block, i) {
|
|
|
|
|
sema_parse(sema, vec_at(n->if_statement.if_block, i));
|
|
|
|
|
}
|
|
|
|
|
@@ -249,8 +421,9 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case SPL_AST_IFVAR_STATEMENT: {
|
|
|
|
|
if (n->ifvar_statement.packed_expr)
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
@@ -259,8 +432,15 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case SPL_AST_WHILE_STATEMENT: {
|
|
|
|
|
if (n->while_statement.expr)
|
|
|
|
|
sema_parse(sema, n->while_statement.expr);
|
|
|
|
|
if (!n->while_statement.expr) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "while statement not have condition expr");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
spl_type_id_t ct = sema_parse(sema, n->while_statement.expr);
|
|
|
|
|
if (!sema_coerce_for_bool(sema, ct)) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "while condition must be bool");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
}
|
|
|
|
|
vec_for(n->while_statement.while_block, i) {
|
|
|
|
|
sema_parse(sema, vec_at(n->while_statement.while_block, i));
|
|
|
|
|
}
|
|
|
|
|
@@ -277,8 +457,9 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
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)
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
@@ -287,7 +468,14 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case SPL_AST_RET_STATEMENT: {
|
|
|
|
|
sema_parse(sema, n->ret_statement.expr);
|
|
|
|
|
if (n->ret_statement.expr) {
|
|
|
|
|
spl_type_id_t tid = sema_parse(sema, n->ret_statement.expr);
|
|
|
|
|
if (sema_coerce(sema, sema->current_fn_ret_tid, tid) != sema->current_fn_ret_tid) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "return type not match");
|
|
|
|
|
sema->error_count += 1;
|
|
|
|
|
}
|
|
|
|
|
n->resolved_type_id = sema->current_fn_ret_tid;
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case SPL_AST_BREAK_STATEMENT:
|
|
|
|
|
case SPL_AST_CONTINUE_STATEMENT:
|
|
|
|
|
@@ -305,7 +493,22 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
if (n->packed_expr.expr)
|
|
|
|
|
sema_parse(sema, n->packed_expr.expr);
|
|
|
|
|
} break;
|
|
|
|
|
case SPL_AST_ASSIGN_EXPR:
|
|
|
|
|
case SPL_AST_ASSIGN_EXPR: {
|
|
|
|
|
spl_type_id_t lt = sema_parse(sema, n->op_expr.left);
|
|
|
|
|
if (lt == 0) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "assign target has no type");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
spl_type_id_t rt = sema_parse(sema, n->op_expr.right);
|
|
|
|
|
if (sema_coerce(sema, lt, rt) == 0) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "assign type mismatch");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
n->resolved_type_id = lt;
|
|
|
|
|
return lt;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_ASSIGN_ADD_EXPR:
|
|
|
|
|
case SPL_AST_ASSIGN_SUB_EXPR:
|
|
|
|
|
case SPL_AST_ASSIGN_MUL_EXPR:
|
|
|
|
|
@@ -315,45 +518,181 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
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_ASSIGN_USHIFT_EXPR: {
|
|
|
|
|
spl_type_id_t lt = sema_parse(sema, n->op_expr.left);
|
|
|
|
|
spl_type_id_t rt = sema_parse(sema, n->op_expr.right);
|
|
|
|
|
if (lt == 0) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "assign target has no type");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (sema_coerce_balance(sema, lt, rt) != lt) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "compound assign result would narrow or mismatch lhs type");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
n->resolved_type_id = lt;
|
|
|
|
|
return lt;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_BOOL_OR_EXPR:
|
|
|
|
|
case SPL_AST_BOOL_AND_EXPR:
|
|
|
|
|
case SPL_AST_BOOL_AND_EXPR: {
|
|
|
|
|
spl_type_id_t lt = sema_parse(sema, n->op_expr.left);
|
|
|
|
|
spl_type_id_t rt = sema_parse(sema, n->op_expr.right);
|
|
|
|
|
spl_type_node_t *ln = spl_type_node(sema->type, lt);
|
|
|
|
|
spl_type_node_t *rn = spl_type_node(sema->type, rt);
|
|
|
|
|
if (!ln || ln->kind != SPL_TYPE_BOOL || !rn || rn->kind != SPL_TYPE_BOOL) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "logical operands must be bool");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
spl_type_id_t bt = spl_type_node_push(sema->type, (spl_type_node_t){.kind = SPL_TYPE_BOOL});
|
|
|
|
|
n->resolved_type_id = bt;
|
|
|
|
|
return bt;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_BIT_OR_EXPR:
|
|
|
|
|
case SPL_AST_BIT_XOR_EXPR:
|
|
|
|
|
case SPL_AST_BIT_AND_EXPR:
|
|
|
|
|
case SPL_AST_BIT_AND_EXPR: {
|
|
|
|
|
spl_type_id_t lt = sema_parse(sema, n->op_expr.left);
|
|
|
|
|
spl_type_id_t rt = sema_parse(sema, n->op_expr.right);
|
|
|
|
|
spl_type_id_t peer = sema_coerce_balance(sema, lt, rt);
|
|
|
|
|
spl_type_node_t *pn = spl_type_node(sema->type, peer);
|
|
|
|
|
if (!pn || pn->kind != SPL_TYPE_INT) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "bitwise operands must be integers");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
n->resolved_type_id = peer;
|
|
|
|
|
return peer;
|
|
|
|
|
}
|
|
|
|
|
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_CMP_GT_EXPR: {
|
|
|
|
|
spl_type_id_t lt = sema_parse(sema, n->op_expr.left);
|
|
|
|
|
spl_type_id_t rt = sema_parse(sema, n->op_expr.right);
|
|
|
|
|
if (sema_coerce_balance(sema, lt, rt) == 0) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "comparison operands type mismatch");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
spl_type_id_t bt = spl_type_node_push(sema->type, (spl_type_node_t){.kind = SPL_TYPE_BOOL});
|
|
|
|
|
n->resolved_type_id = bt;
|
|
|
|
|
return bt;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_RANGE_EXPR:
|
|
|
|
|
break;
|
|
|
|
|
case SPL_AST_LSHIFT_EXPR:
|
|
|
|
|
case SPL_AST_RSHIFT_EXPR:
|
|
|
|
|
case SPL_AST_RSHIFT_EXPR: {
|
|
|
|
|
spl_type_id_t lt = sema_parse(sema, n->op_expr.left);
|
|
|
|
|
spl_type_id_t rt = sema_parse(sema, n->op_expr.right);
|
|
|
|
|
spl_type_node_t *ln = spl_type_node(sema->type, lt);
|
|
|
|
|
spl_type_node_t *rn = spl_type_node(sema->type, rt);
|
|
|
|
|
if (!ln || ln->kind != SPL_TYPE_INT || !rn || rn->kind != SPL_TYPE_INT) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "shift operands must be integers");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
n->resolved_type_id = lt;
|
|
|
|
|
return lt;
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
case SPL_AST_MOD_EXPR: {
|
|
|
|
|
spl_type_id_t lt = sema_parse(sema, n->op_expr.left);
|
|
|
|
|
spl_type_id_t rt = sema_parse(sema, n->op_expr.right);
|
|
|
|
|
spl_type_id_t peer = sema_coerce_balance(sema, lt, rt);
|
|
|
|
|
spl_type_node_t *pn = spl_type_node(sema->type, peer);
|
|
|
|
|
if (!pn || (pn->kind != SPL_TYPE_INT && pn->kind != SPL_TYPE_FLOAT)) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "arithmetic operands type mismatch");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
case SPL_AST_MINUS_EXPR:
|
|
|
|
|
case SPL_AST_NOT_EXPR:
|
|
|
|
|
case SPL_AST_BIT_NOT_EXPR:
|
|
|
|
|
}
|
|
|
|
|
n->resolved_type_id = peer;
|
|
|
|
|
return peer;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_MINUS_EXPR: {
|
|
|
|
|
spl_ast_node_t *op = spl_ast_node(sema->ast, n->prefix_expr.postfix_expr);
|
|
|
|
|
if (op && op->kind == SPL_AST_EXPR_INTEGER_LIT) {
|
|
|
|
|
spl_type_id_t ct = spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = 0,
|
|
|
|
|
.int_type.is_signed = true,
|
|
|
|
|
});
|
|
|
|
|
n->resolved_type_id = ct;
|
|
|
|
|
return ct;
|
|
|
|
|
}
|
|
|
|
|
if (op && op->kind == SPL_AST_EXPR_FLOAT_LIT) {
|
|
|
|
|
spl_type_id_t ct = spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_FLOAT,
|
|
|
|
|
.float_type.bits = 0,
|
|
|
|
|
});
|
|
|
|
|
n->resolved_type_id = ct;
|
|
|
|
|
return ct;
|
|
|
|
|
}
|
|
|
|
|
spl_type_id_t t = sema_parse(sema, n->prefix_expr.postfix_expr);
|
|
|
|
|
spl_type_node_t *tn = spl_type_node(sema->type, t);
|
|
|
|
|
if (!tn || (tn->kind != SPL_TYPE_INT && tn->kind != SPL_TYPE_FLOAT)) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "unary minus requires numeric operand");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
n->resolved_type_id = t;
|
|
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_NOT_EXPR: {
|
|
|
|
|
spl_type_id_t t = sema_parse(sema, n->prefix_expr.postfix_expr);
|
|
|
|
|
spl_type_node_t *tn = spl_type_node(sema->type, t);
|
|
|
|
|
if (!tn || tn->kind != SPL_TYPE_BOOL) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "`not` requires bool operand");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
spl_type_id_t bt = spl_type_node_push(sema->type, (spl_type_node_t){.kind = SPL_TYPE_BOOL});
|
|
|
|
|
n->resolved_type_id = bt;
|
|
|
|
|
return bt;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_BIT_NOT_EXPR: {
|
|
|
|
|
spl_type_id_t t = sema_parse(sema, n->prefix_expr.postfix_expr);
|
|
|
|
|
spl_type_node_t *tn = spl_type_node(sema->type, t);
|
|
|
|
|
if (!tn || tn->kind != SPL_TYPE_INT) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "bitnot requires integer operand");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
n->resolved_type_id = t;
|
|
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_CALL_EXPR: {
|
|
|
|
|
spl_type_id_t fnt = sema_parse(sema, n->postfix_expr.primary_expr);
|
|
|
|
|
spl_type_node_t *fn = spl_type_node(sema->type, fnt);
|
|
|
|
|
if (!fn || fn->kind != SPL_TYPE_FN) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "call target is not a function");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (vec_size(n->postfix_expr.call_expr) != vec_size(fn->fn_type.params)) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "call argument count mismatch");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
vec_for(n->postfix_expr.call_expr, i) {
|
|
|
|
|
spl_type_id_t at = sema_parse(sema, vec_at(n->postfix_expr.call_expr, i));
|
|
|
|
|
if (sema_coerce(sema, vec_at(fn->fn_type.params, i), at) == 0) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "call argument type mismatch");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
n->resolved_type_id = fn->fn_type.ret;
|
|
|
|
|
return fn->fn_type.ret;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_FIELD_EXPR:
|
|
|
|
|
case SPL_AST_DEREF_EXPR:
|
|
|
|
|
if (n->postfix_expr.primary_expr)
|
|
|
|
|
@@ -373,38 +712,84 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
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);
|
|
|
|
|
case SPL_AST_AS_EXPR: {
|
|
|
|
|
spl_type_id_t st = sema_parse(sema, n->postfix_expr.primary_expr);
|
|
|
|
|
spl_type_id_t tt = sema_parse(sema, n->postfix_expr.type_expr);
|
|
|
|
|
spl_type_node_t *sn = spl_type_node(sema->type, st);
|
|
|
|
|
if (tt == 0 || !sn ||
|
|
|
|
|
(sn->kind != SPL_TYPE_INT && sn->kind != SPL_TYPE_FLOAT && sn->kind != SPL_TYPE_BOOL)) {
|
|
|
|
|
SPL_ERROR(&n->dbg, "invalid `as` cast");
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
break;
|
|
|
|
|
case SPL_AST_EXPR_INTEGER_LIT:
|
|
|
|
|
case SPL_AST_EXPR_FLOAT_LIT:
|
|
|
|
|
}
|
|
|
|
|
n->resolved_type_id = tt;
|
|
|
|
|
return tt;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_EXPR_INTEGER_LIT: {
|
|
|
|
|
spl_type_id_t ct = spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = 0,
|
|
|
|
|
.int_type.is_signed = true,
|
|
|
|
|
});
|
|
|
|
|
n->resolved_type_id = ct;
|
|
|
|
|
return ct;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_EXPR_FLOAT_LIT: {
|
|
|
|
|
spl_type_id_t ct = spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_FLOAT,
|
|
|
|
|
.float_type.bits = 0,
|
|
|
|
|
});
|
|
|
|
|
n->resolved_type_id = ct;
|
|
|
|
|
return ct;
|
|
|
|
|
}
|
|
|
|
|
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_NULL: {
|
|
|
|
|
spl_type_id_t nt = spl_type_node_push(sema->type, (spl_type_node_t){.kind = SPL_TYPE_NULL});
|
|
|
|
|
n->resolved_type_id = nt;
|
|
|
|
|
return nt;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_EXPR_TRUE:
|
|
|
|
|
case SPL_AST_EXPR_FALSE: {
|
|
|
|
|
spl_type_id_t bt = spl_type_node_push(sema->type, (spl_type_node_t){.kind = SPL_TYPE_BOOL});
|
|
|
|
|
n->resolved_type_id = bt;
|
|
|
|
|
return bt;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_EXPR_UNDEFINED: {
|
|
|
|
|
spl_type_id_t ut =
|
|
|
|
|
spl_type_node_push(sema->type, (spl_type_node_t){.kind = SPL_TYPE_UNDEFINED});
|
|
|
|
|
n->resolved_type_id = ut;
|
|
|
|
|
return ut;
|
|
|
|
|
}
|
|
|
|
|
case SPL_AST_EXPR_IDENT: {
|
|
|
|
|
spl_symbol_t symbol = {0};
|
|
|
|
|
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;
|
|
|
|
|
sema->error_count++;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
Assert(symbol.node != 0);
|
|
|
|
|
n->resolved_def_id = symbol.node;
|
|
|
|
|
} break;
|
|
|
|
|
spl_def_node_t *d = spl_type_def(sema->type, symbol.node);
|
|
|
|
|
if (!d) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (d->kind == SPL_DEF_VAR || d->kind == SPL_DEF_MEMBER) {
|
|
|
|
|
return d->var_def.type_id;
|
|
|
|
|
}
|
|
|
|
|
return d->type_id;
|
|
|
|
|
}
|
|
|
|
|
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_EXPR_EXPR: {
|
|
|
|
|
spl_type_id_t t = sema_parse(sema, n->primary_expr.expr);
|
|
|
|
|
n->resolved_type_id = t;
|
|
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
@@ -460,20 +845,85 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SPL_AST_TYPE_VOID:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_VOID,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_BOOL:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_BOOL,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_OPAQUE:
|
|
|
|
|
break;
|
|
|
|
|
case SPL_AST_TYPE_I8:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = 8,
|
|
|
|
|
.int_type.is_signed = true,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_U8:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = 8,
|
|
|
|
|
.int_type.is_signed = false,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_I16:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = 16,
|
|
|
|
|
.int_type.is_signed = true,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_U16:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = 16,
|
|
|
|
|
.int_type.is_signed = false,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_I32:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = 32,
|
|
|
|
|
.int_type.is_signed = true,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_U32:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = 32,
|
|
|
|
|
.int_type.is_signed = false,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_I64:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = 64,
|
|
|
|
|
.int_type.is_signed = true,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_U64:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = 64,
|
|
|
|
|
.int_type.is_signed = false,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_ISIZE:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = sizeof(void *) * 8, /* FIXME */
|
|
|
|
|
.int_type.is_signed = true,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_USIZE:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_INT,
|
|
|
|
|
.int_type.bits = sizeof(void *) * 8, /* FIXME */
|
|
|
|
|
.int_type.is_signed = false,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE__F32:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_FLOAT,
|
|
|
|
|
.float_type.bits = 32,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE__F64:
|
|
|
|
|
return spl_type_node_push(sema->type, (spl_type_node_t){
|
|
|
|
|
.kind = SPL_TYPE_FLOAT,
|
|
|
|
|
.float_type.bits = 64,
|
|
|
|
|
});
|
|
|
|
|
case SPL_AST_TYPE_ANY:
|
|
|
|
|
case SPL_AST_TYPE_IDENT:
|
|
|
|
|
break;
|
|
|
|
|
@@ -481,6 +931,7 @@ static void sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|
|
|
|
UNREACHABLE();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void spl_sema_init(spl_sema_t *sema, spl_ast_t *ast, spl_type_t *type, spl_scope_t *scope) {
|
|
|
|
|
@@ -489,6 +940,7 @@ void spl_sema_init(spl_sema_t *sema, spl_ast_t *ast, spl_type_t *type, spl_scope
|
|
|
|
|
sema->type = type;
|
|
|
|
|
sema->scope = scope;
|
|
|
|
|
sema->error_count = 0;
|
|
|
|
|
sema->current_fn_ret_tid = 0;
|
|
|
|
|
sema->root = (spl_symbol_t){0};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|