mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-14 22:38:46 +00:00
HW2 (4)
examples/c 디렉터리 아래에 있는 예제 모두 통과하는 상태
This commit is contained in:
217
src/irgen/mod.rs
217
src/irgen/mod.rs
@@ -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,19 +2100,12 @@ 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)
|
||||
}
|
||||
Ok(ptr)
|
||||
}
|
||||
|
||||
fn translate_typecast(
|
||||
@@ -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"),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user