stage1 支持指针运算 提供新的类型检查计算
This commit is contained in:
1 parent
be41a82d55
commit
06f3884c30
12 files changed
+572
-321
No files matched your search
+46
-11
@@ -239,6 +239,12 @@ static spl_ir_node_ref_t emit_lvalue(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
|
||||
return 0;
|
||||
return slot;
|
||||
}
|
||||
case SPL_AST_EXPR_UNARY: {
|
||||
if (n->unary.op != SPL_UNARY_OP_DEREF)
|
||||
return 0;
|
||||
/* *p 作为左值,地址就是指针 p 的值 */
|
||||
return emit_expr(a, n->unary.operand);
|
||||
}
|
||||
case SPL_AST_EXPR_FIELD: {
|
||||
spl_ast_node_t *obj = spl_ast_node(a->sema->ast, n->field.obj);
|
||||
if (!obj)
|
||||
@@ -298,7 +304,7 @@ static spl_ir_node_ref_t emit_lvalue(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
|
||||
spl_ast_node_t *idx_node = spl_ast_node(a->sema->ast, n->index.index);
|
||||
if (!idx_node || idx_node->kind != SPL_AST_EXPR_INT_LIT)
|
||||
return 0;
|
||||
usize i = (usize)idx_node->int_lit.val;
|
||||
usize i = (usize)idx_node->int_lit.bits;
|
||||
spl_ir_node_ref_t base = emit_lvalue(a, n->index.obj);
|
||||
if (!base)
|
||||
return 0;
|
||||
@@ -415,10 +421,19 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
return 0;
|
||||
|
||||
switch (n->kind) {
|
||||
case SPL_AST_EXPR_INT_LIT:
|
||||
return spl_ir_builder_type_const_int(a->ir, node_ir(a, n), (usize)n->int_lit.val);
|
||||
case SPL_AST_EXPR_INT_LIT: {
|
||||
/* 节点经 coerce 后 resolved 可能是具体 int 或 float。
|
||||
* 值始终存在 int_lit.bits(补码);按 resolved 决定如何构造 IR 常量。 */
|
||||
spl_type_id_t it = node_ir(a, n);
|
||||
spl_type_node_t *itn = spl_type_node(a->sema->type, it);
|
||||
if (itn && itn->kind == SPL_TYPE_FLOAT) {
|
||||
double d = (double)(int64_t)n->int_lit.bits;
|
||||
return spl_ir_builder_type_const_float(a->ir, it, d);
|
||||
}
|
||||
return spl_ir_builder_type_const_int(a->ir, it, (usize)n->int_lit.bits);
|
||||
}
|
||||
case SPL_AST_EXPR_FLOAT_LIT:
|
||||
return spl_ir_builder_type_const_float(a->ir, node_ir(a, n), n->float_lit.val);
|
||||
return spl_ir_builder_type_const_float(a->ir, node_ir(a, n), n->float_lit.bits);
|
||||
case SPL_AST_EXPR_CHAR_LIT:
|
||||
return spl_ir_builder_type_const_char(a->ir, node_ir(a, n), n->char_lit.val);
|
||||
case SPL_AST_EXPR_STRING_LIT: {
|
||||
@@ -464,6 +479,12 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
case SPL_AST_EXPR_UNARY: {
|
||||
if (n->unary.op == SPL_UNARY_OP_ADDRESS)
|
||||
return emit_lvalue(a, n->unary.operand);
|
||||
if (n->unary.op == SPL_UNARY_OP_DEREF) {
|
||||
spl_ir_node_ref_t ptr = emit_lvalue(a, ref);
|
||||
if (!ptr)
|
||||
return 0;
|
||||
return spl_ir_builder_mem_load(a->ir, node_ir(a, n), ptr);
|
||||
}
|
||||
spl_ir_node_ref_t v = emit_expr(a, n->unary.operand);
|
||||
if (!v)
|
||||
return 0;
|
||||
@@ -584,17 +605,31 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
case SPL_OP_RSHIFT:
|
||||
return spl_ir_builder_arith_shr(a->ir, t, l, r);
|
||||
case SPL_OP_CMP_EQ:
|
||||
return spl_ir_builder_cmp_eq(a->ir, t, l, r);
|
||||
case SPL_OP_CMP_NE:
|
||||
return spl_ir_builder_cmp_ne(a->ir, t, l, r);
|
||||
case SPL_OP_CMP_LT:
|
||||
return spl_ir_builder_cmp_lt(a->ir, t, l, r);
|
||||
case SPL_OP_CMP_LE:
|
||||
return spl_ir_builder_cmp_le(a->ir, t, l, r);
|
||||
case SPL_OP_CMP_GT:
|
||||
return spl_ir_builder_cmp_gt(a->ir, t, l, r);
|
||||
case SPL_OP_CMP_GE:
|
||||
return spl_ir_builder_cmp_ge(a->ir, t, l, r);
|
||||
case SPL_OP_CMP_GE: {
|
||||
/* 比较的操作数类型从左侧子节点读(sema 已 coerce 到共同类型) */
|
||||
spl_ast_node_t *cmln = spl_ast_node(a->sema->ast, n->binary.left);
|
||||
spl_type_id_t op_tid = cmln ? node_ir(a, cmln) : 0;
|
||||
switch (op) {
|
||||
case SPL_OP_CMP_EQ:
|
||||
return spl_ir_builder_cmp_eq(a->ir, op_tid, l, r);
|
||||
case SPL_OP_CMP_NE:
|
||||
return spl_ir_builder_cmp_ne(a->ir, op_tid, l, r);
|
||||
case SPL_OP_CMP_LT:
|
||||
return spl_ir_builder_cmp_lt(a->ir, op_tid, l, r);
|
||||
case SPL_OP_CMP_LE:
|
||||
return spl_ir_builder_cmp_le(a->ir, op_tid, l, r);
|
||||
case SPL_OP_CMP_GT:
|
||||
return spl_ir_builder_cmp_gt(a->ir, op_tid, l, r);
|
||||
case SPL_OP_CMP_GE:
|
||||
return spl_ir_builder_cmp_ge(a->ir, op_tid, l, r);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user