examples/c 디렉터리 아래에 있는 예제 모두 통과하는 상태
This commit is contained in:
static
2025-04-08 06:08:29 +00:00
parent 95c43b1d44
commit 52d2c2bfee

View File

@@ -916,16 +916,14 @@ impl IrgenFunc<'_> {
ir::Dtype::Int { .. }
| ir::Dtype::Float { .. }
| ir::Dtype::Pointer { .. }
| ir::Dtype::Array { .. } => {
let value = if let Some(initializer) = &init_decl.node.initializer {
Some(self.translate_initializer(&initializer.node, context)?)
} else {
None
| ir::Dtype::Array { .. }
| ir::Dtype::Struct { .. } => {
let ptr = self.translate_alloc(name, &dtype, context)?;
if let Some(initializer) = &init_decl.node.initializer {
self.translate_initializer(ptr, &initializer.node, context)?;
};
let _unused = self.translate_alloc(name, &dtype, value, context)?;
}
ir::Dtype::Function { .. } => todo!("g"),
ir::Dtype::Struct { .. } => todo!("h"),
ir::Dtype::Typedef { .. } => unreachable!(),
}
}
@@ -934,13 +932,95 @@ impl IrgenFunc<'_> {
fn translate_initializer(
&mut self,
ptr: ir::Operand,
initializer: &Initializer,
context: &mut Context,
) -> Result<ir::Operand, IrgenErrorMessage> {
) -> Result<(), IrgenErrorMessage> {
match initializer {
Initializer::Expression(expr) => self.translate_expr_rvalue(&expr.node, context),
Initializer::List(_) => panic!("Initializer::List is unsupported"),
Initializer::Expression(expr) => {
let value = self.translate_expr_rvalue(&expr.node, context)?;
let dtype = ptr.dtype().get_pointer_inner().cloned().unwrap();
let value = self.translate_typecast(value, dtype, context)?;
let _unused = context.insert_instruction(ir::Instruction::Store { ptr, value })?;
}
Initializer::List(items) => {
let ptr_inner_dtype = ptr.dtype().get_pointer_inner().unwrap().clone();
if let Some(inner) = ptr_inner_dtype.get_array_inner() {
let inner_ptr = ir::Dtype::pointer(inner.clone());
let (inner_size, _) = inner
.size_align_of(self.structs)
.map_err(|e| IrgenErrorMessage::InvalidDtype { dtype_error: e })?;
for (i, item) in items.iter().enumerate() {
if !item.node.designation.is_empty() {
todo!("desiginator initializer list");
}
let ptr = context.insert_instruction(ir::Instruction::GetElementPtr {
ptr: ptr.clone(),
offset: ir::Operand::constant(ir::Constant::int(
(inner_size * i).try_into().unwrap(),
ir::Dtype::int(32),
)),
dtype: inner_ptr.clone(),
})?;
self.translate_initializer(ptr, &item.node.initializer.node, context)?;
}
} else if let Some(name) = ptr_inner_dtype.get_struct_name() {
let struct_dtype = self
.structs
.get(name.as_ref().unwrap())
.cloned()
.unwrap()
.unwrap();
let fields = struct_dtype.get_struct_fields().unwrap().as_ref().unwrap();
let (_, _, field_offsets) = struct_dtype
.get_struct_size_align_offsets()
.unwrap()
.as_ref()
.unwrap();
for ((field, field_offset), item) in fields.iter().zip(field_offsets).zip(items)
{
if !item.node.designation.is_empty() {
todo!("desiginator initializer list");
}
let ptr = context.insert_instruction(ir::Instruction::GetElementPtr {
ptr: ptr.clone(),
offset: ir::Operand::constant(ir::Constant::int(
(*field_offset).try_into().unwrap(),
ir::Dtype::int(32),
)),
dtype: ir::Dtype::pointer(field.deref().clone()),
})?;
self.translate_initializer(ptr, &item.node.initializer.node, context)?;
}
// for (field, item) in fields.iter().zip(items) {
// if !item.node.designation.is_empty() {
// todo!("desiginator initializer list");
// }
// if let Some(field_name) = field.name() {
// let (field_offset, field_dtype) = ptr_inner_dtype
// .get_offset_struct_field(field.name().unwrap(), self.structs)
// .unwrap();
// let ptr =
// context.insert_instruction(ir::Instruction::GetElementPtr {
// ptr: ptr.clone(),
// offset: ir::Operand::constant(ir::Constant::int(
// field_offset.try_into().unwrap(),
// ir::Dtype::int(32),
// )),
// dtype: ir::Dtype::pointer(field_dtype),
// })?;
// self.translate_initializer(ptr, &item.node.initializer.node, context)?;
// } else {
// }
// }
} else {
unreachable!();
}
}
}
Ok(())
}
fn translate_expr_rvalue(
@@ -1025,6 +1105,24 @@ impl IrgenFunc<'_> {
)))
}
Expression::Comma(exprs) => self.translate_comma(exprs.deref(), context),
Expression::Member(member) => {
let member = &member.node;
let ptr = self.translate_member_op(
&member.operator.node,
&member.expression.node,
&member.identifier.node,
context,
)?;
if let Some(inner) = ptr.dtype().get_pointer_inner().unwrap().get_array_inner() {
context.insert_instruction(ir::Instruction::GetElementPtr {
ptr,
offset: ir::Operand::constant(ir::Constant::int(0, ir::Dtype::int(32))),
dtype: ir::Dtype::pointer(inner.clone()),
})
} else {
context.insert_instruction(ir::Instruction::Load { ptr })
}
}
_ => todo!("c"),
}
}
@@ -1071,7 +1169,7 @@ impl IrgenFunc<'_> {
self.translate_typecast(else_val, merged_dtype.clone(), &mut else_context)?;
let var = self.alloc_tempid();
let ptr = self.translate_alloc(var, &merged_dtype.clone(), None, context)?;
let ptr = self.translate_alloc(var, &merged_dtype.clone(), context)?;
let _unused = then_context.insert_instruction(ir::Instruction::Store {
ptr: ptr.clone(),
@@ -1193,6 +1291,11 @@ impl IrgenFunc<'_> {
BinaryOperator::AssignPlus => {
let rhs = self.translate_binary_op(&BinaryOperator::Plus, lhs, rhs, context)?;
let lhs = self.translate_expr_lvalue(lhs, context)?;
let rhs = self.translate_typecast(
rhs,
lhs.dtype().get_pointer_inner().unwrap().clone(),
context,
)?;
let _unused = context.insert_instruction(ir::Instruction::Store {
ptr: lhs,
value: rhs.clone(),
@@ -1202,6 +1305,11 @@ impl IrgenFunc<'_> {
BinaryOperator::AssignMinus => {
let rhs = self.translate_binary_op(&BinaryOperator::Minus, lhs, rhs, context)?;
let lhs = self.translate_expr_lvalue(lhs, context)?;
let rhs = self.translate_typecast(
rhs,
lhs.dtype().get_pointer_inner().unwrap().clone(),
context,
)?;
let _unused = context.insert_instruction(ir::Instruction::Store {
ptr: lhs,
value: rhs.clone(),
@@ -1217,7 +1325,7 @@ impl IrgenFunc<'_> {
);
let tmp = self.alloc_tempid();
let tmp = self.translate_alloc(tmp, &ir::Dtype::BOOL, None, context)?;
let tmp = self.translate_alloc(tmp, &ir::Dtype::BOOL, context)?;
let then_bid = self.alloc_bid();
let else_bid = self.alloc_bid();
@@ -1283,7 +1391,7 @@ impl IrgenFunc<'_> {
);
let tmp = self.alloc_tempid();
let tmp = self.translate_alloc(tmp, &ir::Dtype::BOOL, None, context)?;
let tmp = self.translate_alloc(tmp, &ir::Dtype::BOOL, context)?;
let then_bid = self.alloc_bid();
let else_bid = self.alloc_bid();
@@ -1765,7 +1873,62 @@ impl IrgenFunc<'_> {
BinaryOperator::Index => self.translate_index_op(&binary.node.lhs.node, &binary.node.rhs.node, context),
_ => Err(IrgenErrorMessage::Misc { message: "binary operator expression cannot be used as l-value except index operator expression".to_string() }),
}
_ => todo!("expr lvalue")
Expression::Member(member) => {
let member = &member.node;
self.translate_member_op(&member.operator.node, &member.expression.node, &member.identifier.node, context)
}
Expression::Call(call) => {
let res = self.translate_func_call(&call.node, context)?;
let temp_id = self.alloc_tempid();
let ptr = self.translate_alloc(temp_id, &res.dtype(), context)?;
let _unused = context.insert_instruction(ir::Instruction::Store { ptr: ptr.clone(), value: res })?;
Ok(ptr)
}
_ => {
println!("{}", expr.write_string());
todo!("expr lvalue")
}
}
}
fn translate_member_op(
&mut self,
op: &MemberOperator,
expr: &Expression,
id: &Identifier,
context: &mut Context,
) -> Result<ir::Operand, IrgenErrorMessage> {
match op {
MemberOperator::Direct => {
let expr = self.translate_expr_lvalue(expr, context)?;
let struct_dtype = expr.dtype().get_pointer_inner().unwrap().clone();
let (field_offset, field_dtype) = struct_dtype
.get_offset_struct_field(&id.name, self.structs)
.expect("no field");
context.insert_instruction(ir::Instruction::GetElementPtr {
ptr: expr,
offset: ir::Operand::constant(ir::Constant::int(
field_offset.try_into().unwrap(),
ir::Dtype::int(32),
)),
dtype: ir::Dtype::pointer(field_dtype),
})
}
MemberOperator::Indirect => {
let expr = self.translate_expr_rvalue(expr, context)?;
let struct_dtype = expr.dtype().get_pointer_inner().unwrap().clone();
let (field_offset, field_dtype) = struct_dtype
.get_offset_struct_field(&id.name, self.structs)
.expect("no field");
context.insert_instruction(ir::Instruction::GetElementPtr {
ptr: expr,
offset: ir::Operand::constant(ir::Constant::int(
field_offset.try_into().unwrap(),
ir::Dtype::int(32),
)),
dtype: ir::Dtype::pointer(field_dtype),
})
}
}
}
@@ -1921,11 +2084,11 @@ impl IrgenFunc<'_> {
context: &mut Context,
) -> Result<(), IrgenErrorMessage> {
for (i, (dtype, var)) in izip!(&signature.params, name_of_params).enumerate() {
let value = Some(ir::Operand::register(
ir::RegisterId::arg(bid_init, i),
dtype.clone(),
));
let _unused = self.translate_alloc(var.clone(), dtype, value, context)?;
let ptr = self.translate_alloc(var.clone(), dtype, context)?;
let _unused = context.insert_instruction(ir::Instruction::Store {
ptr,
value: ir::Operand::register(ir::RegisterId::arg(bid_init, i), dtype.clone()),
})?;
self.phinodes_init
.push(Named::new(Some(var.clone()), dtype.clone()));
}
@@ -1937,20 +2100,13 @@ impl IrgenFunc<'_> {
&mut self,
var: String,
dtype: &ir::Dtype,
value: Option<ir::Operand>,
context: &mut Context,
) -> Result<ir::Operand, IrgenErrorMessage> {
let rid = self.insert_alloc(Named::new(Some(var.clone()), dtype.clone()));
let ptr = ir::Operand::register(rid, ir::Dtype::pointer(dtype.clone()));
self.insert_symbol_table_entry(var, ptr.clone())?;
if let Some(value) = value {
let value = self.translate_typecast(value, dtype.clone(), context)?;
context.insert_instruction(ir::Instruction::Store { ptr, value })
} else {
Ok(ptr)
}
}
fn translate_typecast(
&mut self,
@@ -2013,6 +2169,13 @@ impl IrgenFunc<'_> {
.get_pointer_inner()
.cloned()
.unwrap(),
BinaryOperator::Plus
| BinaryOperator::Minus
| BinaryOperator::Multiply
| BinaryOperator::Divide => self.merge_dtype(
self.integer_promotion(self.dtypeof_expr(&binary.lhs.node)),
self.integer_promotion(self.dtypeof_expr(&binary.rhs.node)),
),
_ => todo!("binary dtypeof_expr"),
}
}