완료
This commit is contained in:
static
2025-04-08 12:37:04 +00:00
parent 52d2c2bfee
commit 54e50b4622

View File

@@ -38,10 +38,8 @@ use core::cmp::Ordering;
use core::convert::TryFrom; use core::convert::TryFrom;
use core::{fmt, mem}; use core::{fmt, mem};
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
use std::fmt::Binary;
use std::ops::Deref; use std::ops::Deref;
use ir::BlockExit;
use itertools::izip; use itertools::izip;
use lang_c::ast::*; use lang_c::ast::*;
use lang_c::driver::Parse; use lang_c::driver::Parse;
@@ -992,29 +990,6 @@ impl IrgenFunc<'_> {
})?; })?;
self.translate_initializer(ptr, &item.node.initializer.node, context)?; 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 { } else {
unreachable!(); unreachable!();
} }
@@ -1274,48 +1249,38 @@ impl IrgenFunc<'_> {
context: &mut Context, context: &mut Context,
) -> Result<ir::Operand, IrgenErrorMessage> { ) -> Result<ir::Operand, IrgenErrorMessage> {
match op { match op {
BinaryOperator::Assign => { BinaryOperator::Assign => self.translate_assign(lhs, rhs, None, context),
let lhs = self.translate_expr_lvalue(lhs, context)?; BinaryOperator::AssignMultiply => {
let rhs = self.translate_expr_rvalue(rhs, context)?; self.translate_assign(lhs, rhs, Some(BinaryOperator::Multiply), context)
let rhs = self.translate_typecast( }
rhs, BinaryOperator::AssignDivide => {
lhs.dtype().get_pointer_inner().unwrap().clone(), self.translate_assign(lhs, rhs, Some(BinaryOperator::Divide), context)
context, }
)?; BinaryOperator::AssignModulo => {
let _unused = context.insert_instruction(ir::Instruction::Store { self.translate_assign(lhs, rhs, Some(BinaryOperator::Modulo), context)
ptr: lhs,
value: rhs.clone(),
})?;
Ok(rhs)
} }
BinaryOperator::AssignPlus => { BinaryOperator::AssignPlus => {
let rhs = self.translate_binary_op(&BinaryOperator::Plus, lhs, rhs, context)?; self.translate_assign(lhs, rhs, Some(BinaryOperator::Plus), 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(),
})?;
Ok(rhs)
} }
BinaryOperator::AssignMinus => { BinaryOperator::AssignMinus => {
let rhs = self.translate_binary_op(&BinaryOperator::Minus, lhs, rhs, context)?; self.translate_assign(lhs, rhs, Some(BinaryOperator::Minus), 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(),
})?;
Ok(rhs)
} }
BinaryOperator::AssignShiftLeft => {
self.translate_assign(lhs, rhs, Some(BinaryOperator::ShiftLeft), context)
}
BinaryOperator::AssignShiftRight => {
self.translate_assign(lhs, rhs, Some(BinaryOperator::ShiftRight), context)
}
BinaryOperator::AssignBitwiseAnd => {
self.translate_assign(lhs, rhs, Some(BinaryOperator::BitwiseAnd), context)
}
BinaryOperator::AssignBitwiseXor => {
self.translate_assign(lhs, rhs, Some(BinaryOperator::BitwiseXor), context)
}
BinaryOperator::AssignBitwiseOr => {
self.translate_assign(lhs, rhs, Some(BinaryOperator::BitwiseOr), context)
}
BinaryOperator::LogicalAnd => { BinaryOperator::LogicalAnd => {
let lhs_dtype = self.dtypeof_expr(lhs); let lhs_dtype = self.dtypeof_expr(lhs);
let rhs_dtype = self.dtypeof_expr(rhs); let rhs_dtype = self.dtypeof_expr(rhs);
@@ -1333,76 +1298,15 @@ impl IrgenFunc<'_> {
let lhs = self.translate_expr_rvalue(lhs, context)?; let lhs = self.translate_expr_rvalue(lhs, context)?;
let lhs = self.translate_typecast(lhs, operand_dtype.clone(), context)?; let lhs = self.translate_typecast(lhs, operand_dtype.clone(), context)?;
let condition1 = context.insert_instruction(ir::Instruction::BinOp { let zero = ir::Operand::constant(match operand_dtype {
op: BinaryOperator::NotEquals, ir::Dtype::Int { .. } => ir::Constant::int(0, operand_dtype.clone()),
lhs, ir::Dtype::Float { .. } => ir::Constant::float(0.0, operand_dtype.clone()),
rhs: ir::Operand::constant(ir::Constant::int(0, operand_dtype.clone())), _ => todo!(""),
dtype: ir::Dtype::BOOL,
})?;
self.insert_block(
mem::replace(context, Context::new(end_bid)),
ir::BlockExit::ConditionalJump {
condition: condition1,
arg_then: ir::JumpArg::new(then_bid, Vec::new()),
arg_else: ir::JumpArg::new(else_bid, Vec::new()),
},
);
let mut then_context = Context::new(then_bid);
let _unused = then_context.insert_instruction(ir::Instruction::Store {
ptr: tmp.clone(),
value: ir::Operand::constant(ir::Constant::int(1, ir::Dtype::BOOL)),
})?;
self.insert_block(
then_context,
ir::BlockExit::Jump {
arg: ir::JumpArg::new(end_bid, Vec::new()),
},
);
let mut else_context = Context::new(else_bid);
let rhs = self.translate_expr_rvalue(rhs, &mut else_context)?;
let rhs = self.translate_typecast(rhs, operand_dtype.clone(), &mut else_context)?;
let condition2 = else_context.insert_instruction(ir::Instruction::BinOp {
op: BinaryOperator::NotEquals,
lhs: rhs,
rhs: ir::Operand::constant(ir::Constant::int(1, operand_dtype.clone())),
dtype: ir::Dtype::BOOL,
})?;
let _unused = else_context.insert_instruction(ir::Instruction::Store {
ptr: tmp.clone(),
value: condition2,
}); });
self.insert_block(
else_context,
ir::BlockExit::Jump {
arg: ir::JumpArg::new(end_bid, Vec::new()),
},
);
context.insert_instruction(ir::Instruction::Load { ptr: tmp })
}
BinaryOperator::LogicalOr => {
let lhs_dtype = self.dtypeof_expr(lhs);
let rhs_dtype = self.dtypeof_expr(rhs);
let operand_dtype = self.merge_dtype(
self.integer_promotion(lhs_dtype),
self.integer_promotion(rhs_dtype),
);
let tmp = self.alloc_tempid();
let tmp = self.translate_alloc(tmp, &ir::Dtype::BOOL, context)?;
let then_bid = self.alloc_bid();
let else_bid = self.alloc_bid();
let end_bid = self.alloc_bid();
let lhs = self.translate_expr_rvalue(lhs, context)?;
let lhs = self.translate_typecast(lhs, operand_dtype.clone(), context)?;
let condition1 = context.insert_instruction(ir::Instruction::BinOp { let condition1 = context.insert_instruction(ir::Instruction::BinOp {
op: BinaryOperator::Equals, op: BinaryOperator::Equals,
lhs, lhs,
rhs: ir::Operand::constant(ir::Constant::int(0, operand_dtype.clone())), rhs: zero.clone(),
dtype: ir::Dtype::BOOL, dtype: ir::Dtype::BOOL,
})?; })?;
self.insert_block( self.insert_block(
@@ -1432,7 +1336,83 @@ impl IrgenFunc<'_> {
let condition2 = else_context.insert_instruction(ir::Instruction::BinOp { let condition2 = else_context.insert_instruction(ir::Instruction::BinOp {
op: BinaryOperator::NotEquals, op: BinaryOperator::NotEquals,
lhs: rhs, lhs: rhs,
rhs: ir::Operand::constant(ir::Constant::int(0, operand_dtype.clone())), rhs: zero.clone(),
dtype: ir::Dtype::BOOL,
})?;
let _unused = else_context.insert_instruction(ir::Instruction::Store {
ptr: tmp.clone(),
value: condition2,
});
self.insert_block(
else_context,
ir::BlockExit::Jump {
arg: ir::JumpArg::new(end_bid, Vec::new()),
},
);
context.insert_instruction(ir::Instruction::Load { ptr: tmp })
}
BinaryOperator::LogicalOr => {
// println!(
// "hi~ lhs: {} rhs: {}",
// lhs.write_string(),
// rhs.write_string()
// );
let lhs_dtype = self.dtypeof_expr(lhs);
let rhs_dtype = self.dtypeof_expr(rhs);
let operand_dtype = self.merge_dtype(
self.integer_promotion(lhs_dtype),
self.integer_promotion(rhs_dtype),
);
let tmp = self.alloc_tempid();
let tmp = self.translate_alloc(tmp, &ir::Dtype::BOOL, context)?;
let then_bid = self.alloc_bid();
let else_bid = self.alloc_bid();
let end_bid = self.alloc_bid();
let lhs = self.translate_expr_rvalue(lhs, context)?;
let lhs = self.translate_typecast(lhs, operand_dtype.clone(), context)?;
let zero = ir::Operand::constant(match operand_dtype {
ir::Dtype::Int { .. } => ir::Constant::int(0, operand_dtype.clone()),
ir::Dtype::Float { .. } => ir::Constant::float(0.0, operand_dtype.clone()),
_ => todo!(""),
});
let condition1 = context.insert_instruction(ir::Instruction::BinOp {
op: BinaryOperator::NotEquals,
lhs,
rhs: zero.clone(),
dtype: ir::Dtype::BOOL,
})?;
self.insert_block(
mem::replace(context, Context::new(end_bid)),
ir::BlockExit::ConditionalJump {
condition: condition1,
arg_then: ir::JumpArg::new(then_bid, Vec::new()),
arg_else: ir::JumpArg::new(else_bid, Vec::new()),
},
);
let mut then_context = Context::new(then_bid);
let _unused = then_context.insert_instruction(ir::Instruction::Store {
ptr: tmp.clone(),
value: ir::Operand::constant(ir::Constant::int(1, ir::Dtype::BOOL)),
})?;
self.insert_block(
then_context,
ir::BlockExit::Jump {
arg: ir::JumpArg::new(end_bid, Vec::new()),
},
);
let mut else_context = Context::new(else_bid);
let rhs = self.translate_expr_rvalue(rhs, &mut else_context)?;
let rhs = self.translate_typecast(rhs, operand_dtype.clone(), &mut else_context)?;
let condition2 = else_context.insert_instruction(ir::Instruction::BinOp {
op: BinaryOperator::NotEquals,
lhs: rhs,
rhs: zero.clone(),
dtype: ir::Dtype::BOOL, dtype: ir::Dtype::BOOL,
})?; })?;
let _unused = else_context.insert_instruction(ir::Instruction::Store { let _unused = else_context.insert_instruction(ir::Instruction::Store {
@@ -1488,6 +1468,31 @@ impl IrgenFunc<'_> {
} }
} }
fn translate_assign(
&mut self,
lhs: &Expression,
rhs: &Expression,
op: Option<BinaryOperator>,
context: &mut Context,
) -> Result<ir::Operand, IrgenErrorMessage> {
let rhs = (if let Some(op) = op {
self.translate_binary_op(&op, lhs, rhs, context)
} else {
self.translate_expr_rvalue(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.clone(),
value: rhs.clone(),
})?;
Ok(rhs)
}
fn translate_unary_op( fn translate_unary_op(
&mut self, &mut self,
op: &UnaryOperator, op: &UnaryOperator,
@@ -1583,6 +1588,9 @@ impl IrgenFunc<'_> {
} }
UnaryOperator::Complement => { UnaryOperator::Complement => {
let lhs = self.translate_expr_rvalue(operand, context)?; let lhs = self.translate_expr_rvalue(operand, context)?;
let lhs_dtype = lhs.dtype();
let lhs =
self.translate_typecast(lhs, self.integer_promotion(lhs_dtype), context)?;
let dtype = lhs.dtype(); let dtype = lhs.dtype();
context.insert_instruction(ir::Instruction::BinOp { context.insert_instruction(ir::Instruction::BinOp {
op: BinaryOperator::BitwiseXor, op: BinaryOperator::BitwiseXor,
@@ -1591,8 +1599,14 @@ impl IrgenFunc<'_> {
dtype: dtype.clone(), dtype: dtype.clone(),
}) })
} }
UnaryOperator::Plus | UnaryOperator::Minus | UnaryOperator::Negate => { UnaryOperator::Plus | UnaryOperator::Minus => {
let operand = self.translate_expr_rvalue(operand, context)?; let operand = self.translate_expr_rvalue(operand, context)?;
let operand_dtype = operand.dtype();
let operand = self.translate_typecast(
operand,
self.integer_promotion(operand_dtype),
context,
)?;
let dtype = operand.dtype(); let dtype = operand.dtype();
context.insert_instruction(ir::Instruction::UnaryOp { context.insert_instruction(ir::Instruction::UnaryOp {
op: op.clone(), op: op.clone(),
@@ -1600,6 +1614,27 @@ impl IrgenFunc<'_> {
dtype, dtype,
}) })
} }
UnaryOperator::Negate => {
let lhs = self.translate_expr_rvalue(operand, context)?;
let lhs_dtype = lhs.dtype();
let lhs = self.translate_typecast(
lhs,
self.integer_promotion(lhs_dtype.clone()),
context,
)?;
let lhs_dtype = lhs.dtype();
let rhs = ir::Operand::constant(match &lhs_dtype {
ir::Dtype::Int { .. } => ir::Constant::int(0, lhs_dtype.clone()),
ir::Dtype::Float { .. } => ir::Constant::float(0.0, lhs_dtype.clone()),
_ => todo!(),
});
context.insert_instruction(ir::Instruction::BinOp {
op: BinaryOperator::Equals,
lhs,
rhs,
dtype: ir::Dtype::BOOL,
})
}
_ => todo!("unary op"), _ => todo!("unary op"),
} }
} }
@@ -2084,6 +2119,7 @@ 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() {
// println!("dtype: {}", dtype);
let ptr = self.translate_alloc(var.clone(), dtype, context)?; let ptr = self.translate_alloc(var.clone(), dtype, context)?;
let _unused = context.insert_instruction(ir::Instruction::Store { let _unused = context.insert_instruction(ir::Instruction::Store {
ptr, ptr,
@@ -2129,72 +2165,105 @@ impl IrgenFunc<'_> {
value: ir::Operand, value: ir::Operand,
context: &mut Context, context: &mut Context,
) -> Result<ir::Operand, IrgenErrorMessage> { ) -> Result<ir::Operand, IrgenErrorMessage> {
self.translate_typecast(value, ir::Dtype::BOOL, context) // TODO: Right? let value_dtype = value.dtype();
if value_dtype == ir::Dtype::BOOL {
return Ok(value);
}
let rhs = ir::Operand::constant(match &value_dtype {
ir::Dtype::Int { .. } => ir::Constant::int(0, value_dtype.clone()),
ir::Dtype::Float { .. } => ir::Constant::float(0.0, value_dtype.clone()),
_ => todo!(),
});
context.insert_instruction(ir::Instruction::BinOp {
op: BinaryOperator::NotEquals,
lhs: value,
rhs,
dtype: ir::Dtype::BOOL,
})
} }
fn dtypeof_expr(&self, expr: &Expression) -> ir::Dtype { fn dtypeof_expr(&self, expr: &Expression) -> ir::Dtype {
match expr { match expr {
Expression::Identifier(id) => self.lookup_symbol_table(&id.node.name).unwrap().dtype(), Expression::Identifier(id) => self
.lookup_symbol_table(&id.node.name)
.unwrap()
.dtype()
.get_pointer_inner()
.unwrap()
.clone(),
Expression::Constant(_) => ir::Constant::try_from(expr).unwrap().dtype(), Expression::Constant(_) => ir::Constant::try_from(expr).unwrap().dtype(),
Expression::Call(call) => self
.dtypeof_expr(&call.node.callee.node)
.get_function_inner()
.unwrap()
.0
.clone(),
Expression::SizeOfTy(_) | Expression::SizeOfVal(_) | Expression::AlignOf(_) => {
ir::Dtype::LONGLONG.set_signed(false)
}
Expression::UnaryOperator(unary) => { Expression::UnaryOperator(unary) => {
let unary = &unary.node; let unary = &unary.node;
match unary.operator.node { match unary.operator.node {
UnaryOperator::PreDecrement UnaryOperator::PostIncrement
| UnaryOperator::PreIncrement
| UnaryOperator::PostDecrement | UnaryOperator::PostDecrement
| UnaryOperator::PostIncrement => self.dtypeof_expr(&unary.operand.node), | UnaryOperator::PreIncrement
UnaryOperator::Negate => ir::Dtype::int(32), | UnaryOperator::PreDecrement
_ => todo!("unary dtypeof_expr"), | UnaryOperator::Plus
| UnaryOperator::Minus
| UnaryOperator::Complement => self.dtypeof_expr(&unary.operand.node),
UnaryOperator::Negate => ir::Dtype::INT,
_ => {
println!("{}", unary.write_string());
todo!("unary dtypeof_expr")
}
} }
} }
Expression::BinaryOperator(binary) => { Expression::BinaryOperator(binary) => {
let binary = &binary.node; let binary = &binary.node;
match binary.operator.node { match binary.operator.node {
BinaryOperator::BitwiseAnd BinaryOperator::Multiply
| BinaryOperator::BitwiseOr | BinaryOperator::Divide
| BinaryOperator::BitwiseXor => self.integer_promotion(self.merge_dtype( | BinaryOperator::Modulo
self.dtypeof_expr(&binary.lhs.node), | BinaryOperator::Plus
self.dtypeof_expr(&binary.rhs.node),
)),
BinaryOperator::LogicalAnd
| BinaryOperator::LogicalOr
| BinaryOperator::Equals
| BinaryOperator::NotEquals
| BinaryOperator::Less
| BinaryOperator::LessOrEqual
| BinaryOperator::Greater
| BinaryOperator::GreaterOrEqual => ir::Dtype::BOOL,
BinaryOperator::Assign => self
.dtypeof_expr(&binary.lhs.node)
.get_pointer_inner()
.cloned()
.unwrap(),
BinaryOperator::Plus
| BinaryOperator::Minus | BinaryOperator::Minus
| BinaryOperator::Multiply | BinaryOperator::ShiftLeft
| BinaryOperator::Divide => self.merge_dtype( | BinaryOperator::ShiftRight
| BinaryOperator::BitwiseAnd
| BinaryOperator::BitwiseXor
| BinaryOperator::BitwiseOr => self.merge_dtype(
self.integer_promotion(self.dtypeof_expr(&binary.lhs.node)), self.integer_promotion(self.dtypeof_expr(&binary.lhs.node)),
self.integer_promotion(self.dtypeof_expr(&binary.rhs.node)), self.integer_promotion(self.dtypeof_expr(&binary.rhs.node)),
), ),
_ => todo!("binary dtypeof_expr"), BinaryOperator::Less
| BinaryOperator::Greater
| BinaryOperator::LessOrEqual
| BinaryOperator::GreaterOrEqual
| BinaryOperator::Equals
| BinaryOperator::NotEquals
| BinaryOperator::LogicalAnd
| BinaryOperator::LogicalOr => ir::Dtype::BOOL,
BinaryOperator::Assign
| BinaryOperator::AssignMultiply
| BinaryOperator::AssignDivide
| BinaryOperator::AssignModulo
| BinaryOperator::AssignPlus
| BinaryOperator::AssignMinus
| BinaryOperator::AssignShiftLeft
| BinaryOperator::AssignShiftRight
| BinaryOperator::AssignBitwiseAnd
| BinaryOperator::AssignBitwiseXor
| BinaryOperator::AssignBitwiseOr => self.dtypeof_expr(&binary.lhs.node),
_ => {
println!("{}", binary.write_string());
todo!("binary dtypeof_expr")
}
} }
} }
Expression::SizeOfTy(_) | Expression::SizeOfVal(_) | Expression::AlignOf(_) => {
ir::Dtype::int(64).set_signed(false)
}
Expression::Conditional(cond) => self.merge_dtype( Expression::Conditional(cond) => self.merge_dtype(
self.dtypeof_expr(&cond.node.then_expression.node), self.dtypeof_expr(&cond.node.then_expression.node),
self.dtypeof_expr(&cond.node.else_expression.node), self.dtypeof_expr(&cond.node.else_expression.node),
), ),
Expression::Call(call) => { Expression::Comma(comma) => self.dtypeof_expr(&comma.last().unwrap().node),
let callee_dtype = self.dtypeof_expr(&call.node.callee.node);
let (ret_dtype, _) = callee_dtype
.get_pointer_inner()
.unwrap()
.get_function_inner()
.unwrap();
ret_dtype.clone()
}
_ => { _ => {
println!("{}", expr.write_string()); println!("{}", expr.write_string());
todo!("dtypeof_expr") todo!("dtypeof_expr")