mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-15 15:08:52 +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::Int { .. }
|
||||||
| ir::Dtype::Float { .. }
|
| ir::Dtype::Float { .. }
|
||||||
| ir::Dtype::Pointer { .. }
|
| ir::Dtype::Pointer { .. }
|
||||||
| ir::Dtype::Array { .. } => {
|
| ir::Dtype::Array { .. }
|
||||||
let value = if let Some(initializer) = &init_decl.node.initializer {
|
| ir::Dtype::Struct { .. } => {
|
||||||
Some(self.translate_initializer(&initializer.node, context)?)
|
let ptr = self.translate_alloc(name, &dtype, context)?;
|
||||||
} else {
|
if let Some(initializer) = &init_decl.node.initializer {
|
||||||
None
|
self.translate_initializer(ptr, &initializer.node, context)?;
|
||||||
};
|
};
|
||||||
let _unused = self.translate_alloc(name, &dtype, value, context)?;
|
|
||||||
}
|
}
|
||||||
ir::Dtype::Function { .. } => todo!("g"),
|
ir::Dtype::Function { .. } => todo!("g"),
|
||||||
ir::Dtype::Struct { .. } => todo!("h"),
|
|
||||||
ir::Dtype::Typedef { .. } => unreachable!(),
|
ir::Dtype::Typedef { .. } => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -934,13 +932,95 @@ impl IrgenFunc<'_> {
|
|||||||
|
|
||||||
fn translate_initializer(
|
fn translate_initializer(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
ptr: ir::Operand,
|
||||||
initializer: &Initializer,
|
initializer: &Initializer,
|
||||||
context: &mut Context,
|
context: &mut Context,
|
||||||
) -> Result<ir::Operand, IrgenErrorMessage> {
|
) -> Result<(), IrgenErrorMessage> {
|
||||||
match initializer {
|
match initializer {
|
||||||
Initializer::Expression(expr) => self.translate_expr_rvalue(&expr.node, context),
|
Initializer::Expression(expr) => {
|
||||||
Initializer::List(_) => panic!("Initializer::List is unsupported"),
|
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(
|
fn translate_expr_rvalue(
|
||||||
@@ -1025,6 +1105,24 @@ impl IrgenFunc<'_> {
|
|||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
Expression::Comma(exprs) => self.translate_comma(exprs.deref(), context),
|
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"),
|
_ => todo!("c"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1071,7 +1169,7 @@ impl IrgenFunc<'_> {
|
|||||||
self.translate_typecast(else_val, merged_dtype.clone(), &mut else_context)?;
|
self.translate_typecast(else_val, merged_dtype.clone(), &mut else_context)?;
|
||||||
|
|
||||||
let var = self.alloc_tempid();
|
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 {
|
let _unused = then_context.insert_instruction(ir::Instruction::Store {
|
||||||
ptr: ptr.clone(),
|
ptr: ptr.clone(),
|
||||||
@@ -1193,6 +1291,11 @@ impl IrgenFunc<'_> {
|
|||||||
BinaryOperator::AssignPlus => {
|
BinaryOperator::AssignPlus => {
|
||||||
let rhs = self.translate_binary_op(&BinaryOperator::Plus, lhs, rhs, context)?;
|
let rhs = self.translate_binary_op(&BinaryOperator::Plus, lhs, rhs, context)?;
|
||||||
let lhs = self.translate_expr_lvalue(lhs, 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 {
|
let _unused = context.insert_instruction(ir::Instruction::Store {
|
||||||
ptr: lhs,
|
ptr: lhs,
|
||||||
value: rhs.clone(),
|
value: rhs.clone(),
|
||||||
@@ -1202,6 +1305,11 @@ impl IrgenFunc<'_> {
|
|||||||
BinaryOperator::AssignMinus => {
|
BinaryOperator::AssignMinus => {
|
||||||
let rhs = self.translate_binary_op(&BinaryOperator::Minus, lhs, rhs, context)?;
|
let rhs = self.translate_binary_op(&BinaryOperator::Minus, lhs, rhs, context)?;
|
||||||
let lhs = self.translate_expr_lvalue(lhs, 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 {
|
let _unused = context.insert_instruction(ir::Instruction::Store {
|
||||||
ptr: lhs,
|
ptr: lhs,
|
||||||
value: rhs.clone(),
|
value: rhs.clone(),
|
||||||
@@ -1217,7 +1325,7 @@ impl IrgenFunc<'_> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let tmp = self.alloc_tempid();
|
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 then_bid = self.alloc_bid();
|
||||||
let else_bid = self.alloc_bid();
|
let else_bid = self.alloc_bid();
|
||||||
@@ -1283,7 +1391,7 @@ impl IrgenFunc<'_> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let tmp = self.alloc_tempid();
|
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 then_bid = self.alloc_bid();
|
||||||
let else_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),
|
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() }),
|
_ => 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,
|
context: &mut Context,
|
||||||
) -> Result<(), IrgenErrorMessage> {
|
) -> Result<(), IrgenErrorMessage> {
|
||||||
for (i, (dtype, var)) in izip!(&signature.params, name_of_params).enumerate() {
|
for (i, (dtype, var)) in izip!(&signature.params, name_of_params).enumerate() {
|
||||||
let value = Some(ir::Operand::register(
|
let ptr = self.translate_alloc(var.clone(), dtype, context)?;
|
||||||
ir::RegisterId::arg(bid_init, i),
|
let _unused = context.insert_instruction(ir::Instruction::Store {
|
||||||
dtype.clone(),
|
ptr,
|
||||||
));
|
value: ir::Operand::register(ir::RegisterId::arg(bid_init, i), dtype.clone()),
|
||||||
let _unused = self.translate_alloc(var.clone(), dtype, value, context)?;
|
})?;
|
||||||
self.phinodes_init
|
self.phinodes_init
|
||||||
.push(Named::new(Some(var.clone()), dtype.clone()));
|
.push(Named::new(Some(var.clone()), dtype.clone()));
|
||||||
}
|
}
|
||||||
@@ -1937,19 +2100,12 @@ impl IrgenFunc<'_> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
var: String,
|
var: String,
|
||||||
dtype: &ir::Dtype,
|
dtype: &ir::Dtype,
|
||||||
value: Option<ir::Operand>,
|
|
||||||
context: &mut Context,
|
context: &mut Context,
|
||||||
) -> Result<ir::Operand, IrgenErrorMessage> {
|
) -> Result<ir::Operand, IrgenErrorMessage> {
|
||||||
let rid = self.insert_alloc(Named::new(Some(var.clone()), dtype.clone()));
|
let rid = self.insert_alloc(Named::new(Some(var.clone()), dtype.clone()));
|
||||||
let ptr = ir::Operand::register(rid, ir::Dtype::pointer(dtype.clone()));
|
let ptr = ir::Operand::register(rid, ir::Dtype::pointer(dtype.clone()));
|
||||||
self.insert_symbol_table_entry(var, ptr.clone())?;
|
self.insert_symbol_table_entry(var, ptr.clone())?;
|
||||||
|
Ok(ptr)
|
||||||
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(
|
fn translate_typecast(
|
||||||
@@ -2013,6 +2169,13 @@ impl IrgenFunc<'_> {
|
|||||||
.get_pointer_inner()
|
.get_pointer_inner()
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap(),
|
.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"),
|
_ => todo!("binary dtypeof_expr"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user