완료
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::{fmt, mem};
use std::collections::{BTreeMap, HashMap};
use std::fmt::Binary;
use std::ops::Deref;
use ir::BlockExit;
use itertools::izip;
use lang_c::ast::*;
use lang_c::driver::Parse;
@@ -992,29 +990,6 @@ impl IrgenFunc<'_> {
})?;
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!();
}
@@ -1274,48 +1249,38 @@ impl IrgenFunc<'_> {
context: &mut Context,
) -> Result<ir::Operand, IrgenErrorMessage> {
match op {
BinaryOperator::Assign => {
let lhs = self.translate_expr_lvalue(lhs, context)?;
let rhs = self.translate_expr_rvalue(rhs, 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::Assign => self.translate_assign(lhs, rhs, None, context),
BinaryOperator::AssignMultiply => {
self.translate_assign(lhs, rhs, Some(BinaryOperator::Multiply), context)
}
BinaryOperator::AssignDivide => {
self.translate_assign(lhs, rhs, Some(BinaryOperator::Divide), context)
}
BinaryOperator::AssignModulo => {
self.translate_assign(lhs, rhs, Some(BinaryOperator::Modulo), context)
}
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(),
})?;
Ok(rhs)
self.translate_assign(lhs, rhs, Some(BinaryOperator::Plus), context)
}
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(),
})?;
Ok(rhs)
self.translate_assign(lhs, rhs, Some(BinaryOperator::Minus), context)
}
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 => {
let lhs_dtype = self.dtypeof_expr(lhs);
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_typecast(lhs, operand_dtype.clone(), context)?;
let condition1 = context.insert_instruction(ir::Instruction::BinOp {
op: BinaryOperator::NotEquals,
lhs,
rhs: ir::Operand::constant(ir::Constant::int(0, operand_dtype.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: 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,
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!(""),
});
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 {
op: BinaryOperator::Equals,
lhs,
rhs: ir::Operand::constant(ir::Constant::int(0, operand_dtype.clone())),
rhs: zero.clone(),
dtype: ir::Dtype::BOOL,
})?;
self.insert_block(
@@ -1432,7 +1336,83 @@ impl IrgenFunc<'_> {
let condition2 = else_context.insert_instruction(ir::Instruction::BinOp {
op: BinaryOperator::NotEquals,
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,
})?;
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(
&mut self,
op: &UnaryOperator,
@@ -1583,6 +1588,9 @@ impl IrgenFunc<'_> {
}
UnaryOperator::Complement => {
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();
context.insert_instruction(ir::Instruction::BinOp {
op: BinaryOperator::BitwiseXor,
@@ -1591,8 +1599,14 @@ impl IrgenFunc<'_> {
dtype: dtype.clone(),
})
}
UnaryOperator::Plus | UnaryOperator::Minus | UnaryOperator::Negate => {
UnaryOperator::Plus | UnaryOperator::Minus => {
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();
context.insert_instruction(ir::Instruction::UnaryOp {
op: op.clone(),
@@ -1600,6 +1614,27 @@ impl IrgenFunc<'_> {
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"),
}
}
@@ -2084,6 +2119,7 @@ impl IrgenFunc<'_> {
context: &mut Context,
) -> Result<(), IrgenErrorMessage> {
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 _unused = context.insert_instruction(ir::Instruction::Store {
ptr,
@@ -2129,72 +2165,105 @@ impl IrgenFunc<'_> {
value: ir::Operand,
context: &mut Context,
) -> 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 {
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::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) => {
let unary = &unary.node;
match unary.operator.node {
UnaryOperator::PreDecrement
| UnaryOperator::PreIncrement
UnaryOperator::PostIncrement
| UnaryOperator::PostDecrement
| UnaryOperator::PostIncrement => self.dtypeof_expr(&unary.operand.node),
UnaryOperator::Negate => ir::Dtype::int(32),
_ => todo!("unary dtypeof_expr"),
| UnaryOperator::PreIncrement
| UnaryOperator::PreDecrement
| 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) => {
let binary = &binary.node;
match binary.operator.node {
BinaryOperator::BitwiseAnd
| BinaryOperator::BitwiseOr
| BinaryOperator::BitwiseXor => self.integer_promotion(self.merge_dtype(
self.dtypeof_expr(&binary.lhs.node),
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::Multiply
| BinaryOperator::Divide
| BinaryOperator::Modulo
| BinaryOperator::Plus
| BinaryOperator::Minus
| BinaryOperator::Multiply
| BinaryOperator::Divide => self.merge_dtype(
| BinaryOperator::ShiftLeft
| 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.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(
self.dtypeof_expr(&cond.node.then_expression.node),
self.dtypeof_expr(&cond.node.else_expression.node),
),
Expression::Call(call) => {
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()
}
Expression::Comma(comma) => self.dtypeof_expr(&comma.last().unwrap().node),
_ => {
println!("{}", expr.write_string());
todo!("dtypeof_expr")