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