mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-15 15:08:52 +00:00
HW2 (5)
완료
This commit is contained in:
411
src/irgen/mod.rs
411
src/irgen/mod.rs
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user