Compare commits
No commits in common. "469ce3ce77c5dbf1e48ed264ebbdf4a5cbd19835" and "63c54ae4da1dc4e3ea9423e897cc870047d3937a" have entirely different histories.
469ce3ce77
...
63c54ae4da
@ -1,6 +1,17 @@
|
|||||||
// Arithmetic, function calls and imports!
|
// Arithmetic, function calls and imports!
|
||||||
|
|
||||||
|
import std::print;
|
||||||
|
import std::from_str;
|
||||||
|
import std::add_num_to_str;
|
||||||
|
import std::free_string;
|
||||||
|
|
||||||
fn main() -> u32 {
|
fn main() -> u32 {
|
||||||
|
for i in 0 .. 15 {
|
||||||
|
let mut text = from_str("num: ");
|
||||||
|
add_num_to_str(&mut text, i);
|
||||||
|
print(text);
|
||||||
|
free_string(&text);
|
||||||
|
}
|
||||||
|
|
||||||
let mut num = 0;
|
let mut num = 0;
|
||||||
while num < 10 {
|
while num < 10 {
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
// Arithmetic, function calls and imports!
|
|
||||||
|
|
||||||
|
|
||||||
fn main() -> bool {
|
|
||||||
let bwand = (0xff & 0xf0) >> 4;
|
|
||||||
let bwor = (0x0fu32 | 0x00) << 4;
|
|
||||||
let bwxor = (0xf0 | 0x0f);
|
|
||||||
|
|
||||||
return (bwxor == 255) && ((bwand == 15) || false) && (bwor == 240);
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
// Arithmetic, function calls and imports!
|
|
||||||
|
|
||||||
|
|
||||||
fn main() -> bool {
|
|
||||||
|
|
||||||
return 5.0 > -1;
|
|
||||||
}
|
|
@ -410,8 +410,6 @@ impl Builder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::And(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
Instr::And(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
||||||
Instr::Or(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
|
||||||
Instr::XOr(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
|
||||||
Instr::ICmp(_, lhs, rhs) => {
|
Instr::ICmp(_, lhs, rhs) => {
|
||||||
let t = match_types(&lhs, &rhs, self)?;
|
let t = match_types(&lhs, &rhs, self)?;
|
||||||
if t.category().comparable() || !t.category().integer() {
|
if t.category().comparable() || !t.category().integer() {
|
||||||
@ -530,30 +528,6 @@ impl Builder {
|
|||||||
Instr::PtrToInt(instr, ty) => instr.cast_to(self, &ty).map(|_| ()),
|
Instr::PtrToInt(instr, ty) => instr.cast_to(self, &ty).map(|_| ()),
|
||||||
Instr::IntToPtr(instr, ty) => instr.cast_to(self, &ty).map(|_| ()),
|
Instr::IntToPtr(instr, ty) => instr.cast_to(self, &ty).map(|_| ()),
|
||||||
Instr::BitCast(..) => Ok(()),
|
Instr::BitCast(..) => Ok(()),
|
||||||
Instr::ShiftRightLogical(_, rhs) => {
|
|
||||||
let rhs_ty = rhs.get_type(&self)?;
|
|
||||||
if rhs_ty.category() == TypeCategory::UnsignedInteger {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(ErrorKind::Null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Instr::ShiftRightArithmetic(_, rhs) => {
|
|
||||||
let rhs_ty = rhs.get_type(&self)?;
|
|
||||||
if rhs_ty.category() == TypeCategory::UnsignedInteger {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(ErrorKind::Null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Instr::ShiftLeft(_, rhs) => {
|
|
||||||
let rhs_ty = rhs.get_type(&self)?;
|
|
||||||
if rhs_ty.category() == TypeCategory::UnsignedInteger {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(ErrorKind::Null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -640,8 +614,6 @@ impl InstructionValue {
|
|||||||
SRem(lhs, rhs) => match_types(lhs, rhs, &builder),
|
SRem(lhs, rhs) => match_types(lhs, rhs, &builder),
|
||||||
FRem(lhs, rhs) => match_types(lhs, rhs, &builder),
|
FRem(lhs, rhs) => match_types(lhs, rhs, &builder),
|
||||||
And(lhs, rhs) => match_types(lhs, rhs, &builder),
|
And(lhs, rhs) => match_types(lhs, rhs, &builder),
|
||||||
Or(lhs, rhs) => match_types(lhs, rhs, &builder),
|
|
||||||
XOr(lhs, rhs) => match_types(lhs, rhs, &builder),
|
|
||||||
ICmp(_, _, _) => Ok(Type::Bool),
|
ICmp(_, _, _) => Ok(Type::Bool),
|
||||||
FCmp(_, _, _) => Ok(Type::Bool),
|
FCmp(_, _, _) => Ok(Type::Bool),
|
||||||
FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret),
|
FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret),
|
||||||
@ -702,9 +674,6 @@ impl InstructionValue {
|
|||||||
PtrToInt(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()),
|
PtrToInt(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()),
|
||||||
IntToPtr(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()),
|
IntToPtr(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()),
|
||||||
BitCast(_, ty) => Ok(ty.clone()),
|
BitCast(_, ty) => Ok(ty.clone()),
|
||||||
ShiftRightLogical(lhs, _) => lhs.get_type(builder),
|
|
||||||
ShiftRightArithmetic(lhs, _) => lhs.get_type(builder),
|
|
||||||
ShiftLeft(lhs, _) => lhs.get_type(builder),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -975,31 +975,6 @@ impl InstructionHolder {
|
|||||||
ty.as_llvm(module.context_ref, &module.types),
|
ty.as_llvm(module.context_ref, &module.types),
|
||||||
name.as_ptr(),
|
name.as_ptr(),
|
||||||
),
|
),
|
||||||
Or(lhs, rhs) => {
|
|
||||||
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
|
||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
|
||||||
LLVMBuildOr(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
|
||||||
}
|
|
||||||
XOr(lhs, rhs) => {
|
|
||||||
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
|
||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
|
||||||
LLVMBuildXor(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
|
||||||
}
|
|
||||||
ShiftRightLogical(lhs, rhs) => {
|
|
||||||
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
|
||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
|
||||||
LLVMBuildLShr(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
|
||||||
}
|
|
||||||
ShiftRightArithmetic(lhs, rhs) => {
|
|
||||||
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
|
||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
|
||||||
LLVMBuildAShr(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
|
||||||
}
|
|
||||||
ShiftLeft(lhs, rhs) => {
|
|
||||||
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
|
||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
|
||||||
LLVMBuildShl(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(record) = &self.record {
|
if let Some(record) = &self.record {
|
||||||
|
@ -9,10 +9,10 @@ use crate::{
|
|||||||
CmpPredicate, Context, Instr, InstructionData, TerminatorKind,
|
CmpPredicate, Context, Instr, InstructionData, TerminatorKind,
|
||||||
builder::*,
|
builder::*,
|
||||||
debug_information::{
|
debug_information::{
|
||||||
DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocalVariable, DebugLocation,
|
DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocalVariable,
|
||||||
DebugLocationValue, DebugMetadata, DebugMetadataValue, DebugParamVariable, DebugPointerType, DebugPosition,
|
DebugLocation, DebugLocationValue, DebugMetadata, DebugMetadataValue, DebugParamVariable,
|
||||||
DebugProgramValue, DebugRecordKind, DebugScopeValue, DebugStructType, DebugSubprogramType, DebugTypeData,
|
DebugPointerType, DebugPosition, DebugProgramValue, DebugRecordKind, DebugScopeValue,
|
||||||
DebugTypeHolder, DebugTypeValue,
|
DebugStructType, DebugSubprogramType, DebugTypeData, DebugTypeHolder, DebugTypeValue,
|
||||||
},
|
},
|
||||||
pad_adapter::PadAdapter,
|
pad_adapter::PadAdapter,
|
||||||
};
|
};
|
||||||
@ -68,7 +68,11 @@ impl FunctionHolder {
|
|||||||
.map(|p| format!("{:?}", p))
|
.map(|p| format!("{:?}", p))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
write!(f, "fn {}({}) -> {:?} ", self.data.name, params, self.data.ret)?;
|
write!(
|
||||||
|
f,
|
||||||
|
"fn {}({}) -> {:?} ",
|
||||||
|
self.data.name, params, self.data.ret
|
||||||
|
)?;
|
||||||
|
|
||||||
writeln!(f, "{{")?;
|
writeln!(f, "{{")?;
|
||||||
let mut state = Default::default();
|
let mut state = Default::default();
|
||||||
@ -112,7 +116,11 @@ impl BlockHolder {
|
|||||||
terminator.builder_fmt(&mut inner, builder, debug)?;
|
terminator.builder_fmt(&mut inner, builder, debug)?;
|
||||||
}
|
}
|
||||||
if let Some(location) = self.data.terminator_location {
|
if let Some(location) = self.data.terminator_location {
|
||||||
writeln!(inner, " ^ (At {}) ", debug.as_ref().unwrap().get_location(location))?;
|
writeln!(
|
||||||
|
inner,
|
||||||
|
" ^ (At {}) ",
|
||||||
|
debug.as_ref().unwrap().get_location(location)
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -140,7 +148,11 @@ impl InstructionHolder {
|
|||||||
writeln!(f, " (Debug {} {})", record.variable.hr(debug), kind)?;
|
writeln!(f, " (Debug {} {})", record.variable.hr(debug), kind)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writeln!(f, "{:?} ({}) = {:?} ", self.value, self.name, self.data.kind)?;
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{:?} ({}) = {:?} ",
|
||||||
|
self.value, self.name, self.data.kind
|
||||||
|
)?;
|
||||||
if let Some(debug) = debug {
|
if let Some(debug) = debug {
|
||||||
if let Some(location) = self.data.location {
|
if let Some(location) = self.data.location {
|
||||||
writeln!(f, " ^ (At {}) ", debug.get_location(location))?;
|
writeln!(f, " ^ (At {}) ", debug.get_location(location))?;
|
||||||
@ -176,9 +188,9 @@ impl TerminatorKind {
|
|||||||
impl DebugMetadataValue {
|
impl DebugMetadataValue {
|
||||||
fn hr(&self, debug: &DebugInformation) -> String {
|
fn hr(&self, debug: &DebugInformation) -> String {
|
||||||
let kind = match debug.get_metadata(*self) {
|
let kind = match debug.get_metadata(*self) {
|
||||||
DebugMetadata::ParamVar(DebugParamVariable { name, arg_idx, ty, .. }) => {
|
DebugMetadata::ParamVar(DebugParamVariable {
|
||||||
format!("param {} (idx {}) (type {:?}) ", name, arg_idx, ty)
|
name, arg_idx, ty, ..
|
||||||
}
|
}) => format!("param {} (idx {}) (type {:?}) ", name, arg_idx, ty),
|
||||||
DebugMetadata::LocalVar(DebugLocalVariable { name, ty, .. }) => {
|
DebugMetadata::LocalVar(DebugLocalVariable { name, ty, .. }) => {
|
||||||
format!("var {} (type {:?}) ", name, ty)
|
format!("var {} (type {:?}) ", name, ty)
|
||||||
}
|
}
|
||||||
@ -241,11 +253,14 @@ impl Debug for FunctionHolder {
|
|||||||
impl Debug for BlockHolder {
|
impl Debug for BlockHolder {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let deleted = if self.data.deleted { " (deleted)" } else { "" };
|
let deleted = if self.data.deleted { " (deleted)" } else { "" };
|
||||||
f.debug_tuple(&format!("{}[{:?}]{} ", &self.data.name, &self.value, deleted))
|
f.debug_tuple(&format!(
|
||||||
.field(&self.instructions)
|
"{}[{:?}]{} ",
|
||||||
.field(&self.data.terminator)
|
&self.data.name, &self.value, deleted
|
||||||
.field(&self.data.terminator_location)
|
))
|
||||||
.finish()
|
.field(&self.instructions)
|
||||||
|
.field(&self.data.terminator)
|
||||||
|
.field(&self.data.terminator_location)
|
||||||
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +303,11 @@ impl Debug for BlockValue {
|
|||||||
|
|
||||||
impl Debug for InstructionValue {
|
impl Debug for InstructionValue {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "%{}.{}.{}.{}", self.0.0.0.0, self.0.0.1, self.0.1, self.1)
|
write!(
|
||||||
|
f,
|
||||||
|
"%{}.{}.{}.{}",
|
||||||
|
self.0.0.0.0, self.0.0.1, self.0.1, self.1
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +369,9 @@ impl Debug for Instr {
|
|||||||
fmt_index(f, instruction_value, &index.to_string())?;
|
fmt_index(f, instruction_value, &index.to_string())?;
|
||||||
write!(f, ")")
|
write!(f, ")")
|
||||||
}
|
}
|
||||||
Instr::ExtractValue(instruction_value, index) => fmt_index(f, instruction_value, &index.to_string()),
|
Instr::ExtractValue(instruction_value, index) => {
|
||||||
|
fmt_index(f, instruction_value, &index.to_string())
|
||||||
|
}
|
||||||
Instr::Trunc(instr_val, ty) => {
|
Instr::Trunc(instr_val, ty) => {
|
||||||
write!(f, "{:?} to {:?} ({})", instr_val, ty, self.default_name())
|
write!(f, "{:?} to {:?} ({})", instr_val, ty, self.default_name())
|
||||||
}
|
}
|
||||||
@ -387,11 +408,6 @@ impl Debug for Instr {
|
|||||||
Instr::BitCast(instr_val, ty) => {
|
Instr::BitCast(instr_val, ty) => {
|
||||||
write!(f, "{:?} to {:?} ({})", instr_val, ty, self.default_name())
|
write!(f, "{:?} to {:?} ({})", instr_val, ty, self.default_name())
|
||||||
}
|
}
|
||||||
Instr::Or(lhs, rhs) => fmt_binop(f, lhs, &"||", rhs),
|
|
||||||
Instr::XOr(lhs, rhs) => fmt_binop(f, lhs, &"^", rhs),
|
|
||||||
Instr::ShiftRightLogical(lhs, rhs) => fmt_binop(f, lhs, &">>l", rhs),
|
|
||||||
Instr::ShiftRightArithmetic(lhs, rhs) => fmt_binop(f, lhs, &">>a", rhs),
|
|
||||||
Instr::ShiftLeft(lhs, rhs) => fmt_binop(f, lhs, &"<<", rhs),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -563,7 +579,11 @@ impl Debug for DebugScopeValue {
|
|||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Scope[{}]",
|
"Scope[{}]",
|
||||||
self.0.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(", ")
|
self.0
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,11 +251,6 @@ impl Instr {
|
|||||||
Instr::PtrToInt(_, _) => "ptrtoint",
|
Instr::PtrToInt(_, _) => "ptrtoint",
|
||||||
Instr::IntToPtr(_, _) => "inttoptr",
|
Instr::IntToPtr(_, _) => "inttoptr",
|
||||||
Instr::BitCast(_, _) => "bitcast",
|
Instr::BitCast(_, _) => "bitcast",
|
||||||
Instr::Or(..) => "or",
|
|
||||||
Instr::XOr(..) => "xor",
|
|
||||||
Instr::ShiftRightLogical(..) => "lshr",
|
|
||||||
Instr::ShiftRightArithmetic(..) => "ashr",
|
|
||||||
Instr::ShiftLeft(..) => "shl",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -374,14 +369,7 @@ pub enum Instr {
|
|||||||
SRem(InstructionValue, InstructionValue),
|
SRem(InstructionValue, InstructionValue),
|
||||||
/// Get the remainder from two floats
|
/// Get the remainder from two floats
|
||||||
FRem(InstructionValue, InstructionValue),
|
FRem(InstructionValue, InstructionValue),
|
||||||
|
|
||||||
And(InstructionValue, InstructionValue),
|
And(InstructionValue, InstructionValue),
|
||||||
Or(InstructionValue, InstructionValue),
|
|
||||||
XOr(InstructionValue, InstructionValue),
|
|
||||||
ShiftRightLogical(InstructionValue, InstructionValue),
|
|
||||||
ShiftRightArithmetic(InstructionValue, InstructionValue),
|
|
||||||
ShiftLeft(InstructionValue, InstructionValue),
|
|
||||||
|
|
||||||
Phi(Vec<InstructionValue>),
|
Phi(Vec<InstructionValue>),
|
||||||
|
|
||||||
Alloca(Type),
|
Alloca(Type),
|
||||||
|
@ -88,10 +88,6 @@ pub enum Token {
|
|||||||
LessThan,
|
LessThan,
|
||||||
/// `&`
|
/// `&`
|
||||||
Et,
|
Et,
|
||||||
/// `|`
|
|
||||||
Pipe,
|
|
||||||
/// `^`
|
|
||||||
Hat,
|
|
||||||
/// `!`
|
/// `!`
|
||||||
Exclamation,
|
Exclamation,
|
||||||
|
|
||||||
@ -178,8 +174,6 @@ impl ToString for Token {
|
|||||||
Token::GreaterThan => String::from('>'),
|
Token::GreaterThan => String::from('>'),
|
||||||
Token::LessThan => String::from('<'),
|
Token::LessThan => String::from('<'),
|
||||||
Token::Et => String::from('&'),
|
Token::Et => String::from('&'),
|
||||||
Token::Pipe => String::from('|'),
|
|
||||||
Token::Hat => String::from('^'),
|
|
||||||
Token::Exclamation => String::from('!'),
|
Token::Exclamation => String::from('!'),
|
||||||
Token::ParenOpen => String::from('('),
|
Token::ParenOpen => String::from('('),
|
||||||
Token::ParenClose => String::from(')'),
|
Token::ParenClose => String::from(')'),
|
||||||
@ -417,8 +411,6 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
|
|||||||
'>' => Token::GreaterThan,
|
'>' => Token::GreaterThan,
|
||||||
'<' => Token::LessThan,
|
'<' => Token::LessThan,
|
||||||
'&' => Token::Et,
|
'&' => Token::Et,
|
||||||
'|' => Token::Pipe,
|
|
||||||
'^' => Token::Hat,
|
|
||||||
'!' => Token::Exclamation,
|
'!' => Token::Exclamation,
|
||||||
'(' => Token::ParenOpen,
|
'(' => Token::ParenOpen,
|
||||||
')' => Token::ParenClose,
|
')' => Token::ParenClose,
|
||||||
|
@ -116,14 +116,7 @@ pub enum BinaryOperator {
|
|||||||
Div,
|
Div,
|
||||||
Mod,
|
Mod,
|
||||||
|
|
||||||
BitshiftRight,
|
|
||||||
BitshiftLeft,
|
|
||||||
|
|
||||||
And,
|
And,
|
||||||
Or,
|
|
||||||
Xor,
|
|
||||||
BWAnd,
|
|
||||||
BWOr,
|
|
||||||
LT,
|
LT,
|
||||||
LE,
|
LE,
|
||||||
GT,
|
GT,
|
||||||
@ -133,7 +126,7 @@ pub enum BinaryOperator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BinaryOperator {
|
impl BinaryOperator {
|
||||||
pub fn get_precedence(&self) -> u8 {
|
pub fn get_precedence(&self) -> i8 {
|
||||||
use BinaryOperator::*;
|
use BinaryOperator::*;
|
||||||
match &self {
|
match &self {
|
||||||
Minus => 5,
|
Minus => 5,
|
||||||
@ -141,20 +134,13 @@ impl BinaryOperator {
|
|||||||
Mult => 15,
|
Mult => 15,
|
||||||
Div => 20,
|
Div => 20,
|
||||||
Mod => 20,
|
Mod => 20,
|
||||||
BWAnd => 90,
|
And => 100,
|
||||||
BWOr => 90,
|
LT => 100,
|
||||||
BWXor => 90,
|
LE => 100,
|
||||||
BitshiftLeft => 100,
|
GT => 100,
|
||||||
BitshiftRight => 100,
|
GE => 100,
|
||||||
And => 150,
|
EQ => 100,
|
||||||
Or => 150,
|
NE => 100,
|
||||||
Xor => 150,
|
|
||||||
LT => 150,
|
|
||||||
LE => 150,
|
|
||||||
GT => 150,
|
|
||||||
GE => 150,
|
|
||||||
EQ => 150,
|
|
||||||
NE => 150,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -488,10 +488,6 @@ impl Parse for BinaryOperator {
|
|||||||
stream.next();
|
stream.next();
|
||||||
BinaryOperator::And
|
BinaryOperator::And
|
||||||
}
|
}
|
||||||
(Some(Token::Pipe), Some(Token::Pipe)) => {
|
|
||||||
stream.next();
|
|
||||||
BinaryOperator::Or
|
|
||||||
}
|
|
||||||
(Some(Token::LessThan), Some(Token::Equals)) => {
|
(Some(Token::LessThan), Some(Token::Equals)) => {
|
||||||
stream.next();
|
stream.next();
|
||||||
BinaryOperator::LE
|
BinaryOperator::LE
|
||||||
@ -508,18 +504,6 @@ impl Parse for BinaryOperator {
|
|||||||
stream.next();
|
stream.next();
|
||||||
BinaryOperator::NE
|
BinaryOperator::NE
|
||||||
}
|
}
|
||||||
(Some(Token::GreaterThan), Some(Token::GreaterThan)) => {
|
|
||||||
stream.next();
|
|
||||||
BinaryOperator::BitshiftRight
|
|
||||||
}
|
|
||||||
(Some(Token::LessThan), Some(Token::LessThan)) => {
|
|
||||||
stream.next();
|
|
||||||
BinaryOperator::BitshiftLeft
|
|
||||||
}
|
|
||||||
|
|
||||||
(Some(Token::Hat), _) => BinaryOperator::Xor,
|
|
||||||
(Some(Token::Et), _) => BinaryOperator::BWAnd,
|
|
||||||
(Some(Token::Pipe), _) => BinaryOperator::BWOr,
|
|
||||||
|
|
||||||
(Some(Token::LessThan), _) => BinaryOperator::LT,
|
(Some(Token::LessThan), _) => BinaryOperator::LT,
|
||||||
(Some(Token::GreaterThan), _) => BinaryOperator::GT,
|
(Some(Token::GreaterThan), _) => BinaryOperator::GT,
|
||||||
|
@ -446,21 +446,15 @@ impl ast::BinaryOperator {
|
|||||||
ast::BinaryOperator::Add => mir::BinaryOperator::Add,
|
ast::BinaryOperator::Add => mir::BinaryOperator::Add,
|
||||||
ast::BinaryOperator::Minus => mir::BinaryOperator::Minus,
|
ast::BinaryOperator::Minus => mir::BinaryOperator::Minus,
|
||||||
ast::BinaryOperator::Mult => mir::BinaryOperator::Mult,
|
ast::BinaryOperator::Mult => mir::BinaryOperator::Mult,
|
||||||
|
ast::BinaryOperator::And => mir::BinaryOperator::And,
|
||||||
ast::BinaryOperator::Div => mir::BinaryOperator::Div,
|
ast::BinaryOperator::Div => mir::BinaryOperator::Div,
|
||||||
ast::BinaryOperator::Mod => mir::BinaryOperator::Mod,
|
ast::BinaryOperator::Mod => mir::BinaryOperator::Mod,
|
||||||
ast::BinaryOperator::And => mir::BinaryOperator::And,
|
|
||||||
ast::BinaryOperator::Or => mir::BinaryOperator::Or,
|
|
||||||
ast::BinaryOperator::LT => mir::BinaryOperator::Cmp(mir::CmpOperator::LT),
|
ast::BinaryOperator::LT => mir::BinaryOperator::Cmp(mir::CmpOperator::LT),
|
||||||
ast::BinaryOperator::LE => mir::BinaryOperator::Cmp(mir::CmpOperator::LE),
|
ast::BinaryOperator::LE => mir::BinaryOperator::Cmp(mir::CmpOperator::LE),
|
||||||
ast::BinaryOperator::GT => mir::BinaryOperator::Cmp(mir::CmpOperator::GT),
|
ast::BinaryOperator::GT => mir::BinaryOperator::Cmp(mir::CmpOperator::GT),
|
||||||
ast::BinaryOperator::GE => mir::BinaryOperator::Cmp(mir::CmpOperator::GE),
|
ast::BinaryOperator::GE => mir::BinaryOperator::Cmp(mir::CmpOperator::GE),
|
||||||
ast::BinaryOperator::EQ => mir::BinaryOperator::Cmp(mir::CmpOperator::EQ),
|
ast::BinaryOperator::EQ => mir::BinaryOperator::Cmp(mir::CmpOperator::EQ),
|
||||||
ast::BinaryOperator::NE => mir::BinaryOperator::Cmp(mir::CmpOperator::NE),
|
ast::BinaryOperator::NE => mir::BinaryOperator::Cmp(mir::CmpOperator::NE),
|
||||||
ast::BinaryOperator::BitshiftRight => mir::BinaryOperator::BitshiftRight,
|
|
||||||
ast::BinaryOperator::BitshiftLeft => mir::BinaryOperator::BitshiftLeft,
|
|
||||||
ast::BinaryOperator::Xor => mir::BinaryOperator::Xor,
|
|
||||||
ast::BinaryOperator::BWAnd => mir::BinaryOperator::BitAnd,
|
|
||||||
ast::BinaryOperator::BWOr => mir::BinaryOperator::BitOr,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::ops::BitAnd;
|
|
||||||
|
|
||||||
use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValue, Instr, Type};
|
use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValue, Instr, Type};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -86,21 +84,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn complex_binop_def<T: Clone + 'static>(op: BinaryOperator, lhs: &TypeKind, rhs: &TypeKind, fun: T) -> BinopDefinition
|
|
||||||
where
|
|
||||||
T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue,
|
|
||||||
{
|
|
||||||
BinopDefinition {
|
|
||||||
lhs: ("lhs".to_owned(), lhs.clone()),
|
|
||||||
op,
|
|
||||||
rhs: ("rhs".to_owned(), rhs.clone()),
|
|
||||||
return_type: lhs.clone(),
|
|
||||||
fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))),
|
|
||||||
meta: Default::default(),
|
|
||||||
exported: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn boolean_binop_def<T: Clone + 'static>(op: BinaryOperator, ty: &TypeKind, fun: T) -> BinopDefinition
|
fn boolean_binop_def<T: Clone + 'static>(op: BinaryOperator, ty: &TypeKind, fun: T) -> BinopDefinition
|
||||||
where
|
where
|
||||||
T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue,
|
T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue,
|
||||||
@ -162,39 +145,6 @@ pub fn form_intrinsic_binops() -> Vec<BinopDefinition> {
|
|||||||
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::LE), &ty, |scope, lhs, rhs| {
|
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::LE), &ty, |scope, lhs, rhs| {
|
||||||
scope.block.build(Instr::ICmp(CmpPredicate::LE, lhs, rhs)).unwrap()
|
scope.block.build(Instr::ICmp(CmpPredicate::LE, lhs, rhs)).unwrap()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Bitwise operations
|
|
||||||
intrinsics.push(simple_binop_def(BitOr, &ty, |scope, lhs, rhs| {
|
|
||||||
scope.block.build(Instr::Or(lhs, rhs)).unwrap()
|
|
||||||
}));
|
|
||||||
intrinsics.push(simple_binop_def(BitAnd, &ty, |scope, lhs, rhs| {
|
|
||||||
scope.block.build(Instr::And(lhs, rhs)).unwrap()
|
|
||||||
}));
|
|
||||||
|
|
||||||
intrinsics.push(complex_binop_def(Xor, &ty, &TypeKind::U64, |scope, lhs, rhs| {
|
|
||||||
scope.block.build(Instr::XOr(lhs, rhs)).unwrap()
|
|
||||||
}));
|
|
||||||
if ty.signed() {
|
|
||||||
intrinsics.push(complex_binop_def(
|
|
||||||
BitshiftRight,
|
|
||||||
&ty,
|
|
||||||
&TypeKind::U64,
|
|
||||||
|scope, lhs, rhs| scope.block.build(Instr::ShiftRightArithmetic(lhs, rhs)).unwrap(),
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
intrinsics.push(complex_binop_def(
|
|
||||||
BitshiftRight,
|
|
||||||
&ty,
|
|
||||||
&TypeKind::U64,
|
|
||||||
|scope, lhs, rhs| scope.block.build(Instr::ShiftRightLogical(lhs, rhs)).unwrap(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
intrinsics.push(complex_binop_def(
|
|
||||||
BitshiftLeft,
|
|
||||||
&ty,
|
|
||||||
&TypeKind::U64,
|
|
||||||
|scope, lhs, rhs| scope.block.build(Instr::ShiftLeft(lhs, rhs)).unwrap(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
for ty in INTEGERS.iter().chain(&[TypeKind::Bool, TypeKind::Char]) {
|
for ty in INTEGERS.iter().chain(&[TypeKind::Bool, TypeKind::Char]) {
|
||||||
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::EQ), &ty, |scope, lhs, rhs| {
|
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::EQ), &ty, |scope, lhs, rhs| {
|
||||||
@ -245,12 +195,6 @@ pub fn form_intrinsic_binops() -> Vec<BinopDefinition> {
|
|||||||
intrinsics.push(boolean_binop_def(And, &TypeKind::Bool, |scope, lhs, rhs| {
|
intrinsics.push(boolean_binop_def(And, &TypeKind::Bool, |scope, lhs, rhs| {
|
||||||
scope.block.build(Instr::And(lhs, rhs)).unwrap()
|
scope.block.build(Instr::And(lhs, rhs)).unwrap()
|
||||||
}));
|
}));
|
||||||
intrinsics.push(boolean_binop_def(Or, &TypeKind::Bool, |scope, lhs, rhs| {
|
|
||||||
scope.block.build(Instr::Or(lhs, rhs)).unwrap()
|
|
||||||
}));
|
|
||||||
intrinsics.push(boolean_binop_def(Xor, &TypeKind::Bool, |scope, lhs, rhs| {
|
|
||||||
scope.block.build(Instr::XOr(lhs, rhs)).unwrap()
|
|
||||||
}));
|
|
||||||
|
|
||||||
intrinsics
|
intrinsics
|
||||||
}
|
}
|
||||||
|
@ -885,30 +885,6 @@ impl mir::Expression {
|
|||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
Instr::Sub(lhs, mul)
|
Instr::Sub(lhs, mul)
|
||||||
}
|
}
|
||||||
(mir::BinaryOperator::Or, true, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::Or, true, false) => todo!(),
|
|
||||||
(mir::BinaryOperator::Or, false, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::Or, false, false) => todo!(),
|
|
||||||
(mir::BinaryOperator::Xor, true, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::Xor, true, false) => todo!(),
|
|
||||||
(mir::BinaryOperator::Xor, false, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::Xor, false, false) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitOr, true, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitOr, true, false) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitOr, false, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitOr, false, false) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitAnd, true, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitAnd, true, false) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitAnd, false, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitAnd, false, false) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitshiftRight, true, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitshiftRight, true, false) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitshiftRight, false, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitshiftRight, false, false) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitshiftLeft, true, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitshiftLeft, true, false) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitshiftLeft, false, true) => todo!(),
|
|
||||||
(mir::BinaryOperator::BitshiftLeft, false, false) => todo!(),
|
|
||||||
};
|
};
|
||||||
Some(StackValue(
|
Some(StackValue(
|
||||||
StackValueKind::Immutable(
|
StackValueKind::Immutable(
|
||||||
|
@ -352,12 +352,6 @@ impl Display for BinaryOperator {
|
|||||||
BinaryOperator::Cmp(op) => Display::fmt(op, f),
|
BinaryOperator::Cmp(op) => Display::fmt(op, f),
|
||||||
BinaryOperator::Div => write!(f, "/"),
|
BinaryOperator::Div => write!(f, "/"),
|
||||||
BinaryOperator::Mod => write!(f, "%"),
|
BinaryOperator::Mod => write!(f, "%"),
|
||||||
BinaryOperator::Or => write!(f, "||"),
|
|
||||||
BinaryOperator::Xor => write!(f, "^"),
|
|
||||||
BinaryOperator::BitOr => write!(f, "|"),
|
|
||||||
BinaryOperator::BitAnd => write!(f, "&"),
|
|
||||||
BinaryOperator::BitshiftRight => write!(f, ">>"),
|
|
||||||
BinaryOperator::BitshiftLeft => write!(f, "<<"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,40 @@ enum BlockReturn<'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TypeKind {
|
impl TypeKind {
|
||||||
|
/// Return the type that is the result of a binary operator between two
|
||||||
|
/// values of this type
|
||||||
|
pub fn simple_binop_type(&self, op: &BinaryOperator) -> Option<TypeKind> {
|
||||||
|
if !self.category().is_simple_maths() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(match op {
|
||||||
|
BinaryOperator::Add => self.clone(),
|
||||||
|
BinaryOperator::Minus => self.clone(),
|
||||||
|
BinaryOperator::Mult => self.clone(),
|
||||||
|
BinaryOperator::And => TypeKind::Bool,
|
||||||
|
BinaryOperator::Cmp(_) => TypeKind::Bool,
|
||||||
|
BinaryOperator::Div => self.clone(),
|
||||||
|
BinaryOperator::Mod => self.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reverse of binop_type, where the given hint is the known required output
|
||||||
|
/// type of the binop, and the output is the hint for the lhs/rhs type.
|
||||||
|
pub fn simple_binop_hint(&self, op: &BinaryOperator) -> Option<TypeKind> {
|
||||||
|
if !self.category().is_simple_maths() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
match op {
|
||||||
|
BinaryOperator::Add
|
||||||
|
| BinaryOperator::Minus
|
||||||
|
| BinaryOperator::Mult
|
||||||
|
| BinaryOperator::Div
|
||||||
|
| BinaryOperator::Mod => Some(self.clone()),
|
||||||
|
BinaryOperator::And => None,
|
||||||
|
BinaryOperator::Cmp(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn signed(&self) -> bool {
|
pub fn signed(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
TypeKind::Bool => false,
|
TypeKind::Bool => false,
|
||||||
@ -206,12 +240,6 @@ impl BinaryOperator {
|
|||||||
CmpOperator::EQ => true,
|
CmpOperator::EQ => true,
|
||||||
CmpOperator::NE => true,
|
CmpOperator::NE => true,
|
||||||
},
|
},
|
||||||
BinaryOperator::Or => true,
|
|
||||||
BinaryOperator::Xor => true,
|
|
||||||
BinaryOperator::BitOr => true,
|
|
||||||
BinaryOperator::BitAnd => true,
|
|
||||||
BinaryOperator::BitshiftRight => false,
|
|
||||||
BinaryOperator::BitshiftLeft => false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -479,12 +507,6 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a % b)
|
maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a % b)
|
||||||
}
|
}
|
||||||
BinaryOperator::Or => None,
|
|
||||||
BinaryOperator::Xor => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a ^ b),
|
|
||||||
BinaryOperator::BitOr => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a | b),
|
|
||||||
BinaryOperator::BitAnd => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a & b),
|
|
||||||
BinaryOperator::BitshiftRight => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a >> b),
|
|
||||||
BinaryOperator::BitshiftLeft => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a << b),
|
|
||||||
},
|
},
|
||||||
ExprKind::FunctionCall(..) => None,
|
ExprKind::FunctionCall(..) => None,
|
||||||
ExprKind::If(_) => None,
|
ExprKind::If(_) => None,
|
||||||
|
@ -222,12 +222,6 @@ pub enum BinaryOperator {
|
|||||||
Div,
|
Div,
|
||||||
Mod,
|
Mod,
|
||||||
And,
|
And,
|
||||||
Or,
|
|
||||||
Xor,
|
|
||||||
BitOr,
|
|
||||||
BitAnd,
|
|
||||||
BitshiftRight,
|
|
||||||
BitshiftLeft,
|
|
||||||
Cmp(CmpOperator),
|
Cmp(CmpOperator),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,14 +135,7 @@ impl TypeKind {
|
|||||||
| TypeKind::U16
|
| TypeKind::U16
|
||||||
| TypeKind::U32
|
| TypeKind::U32
|
||||||
| TypeKind::U64
|
| TypeKind::U64
|
||||||
| TypeKind::U128
|
| TypeKind::U128 => Ok(other.clone()),
|
||||||
| TypeKind::F16
|
|
||||||
| TypeKind::F32B
|
|
||||||
| TypeKind::F32
|
|
||||||
| TypeKind::F64
|
|
||||||
| TypeKind::F80
|
|
||||||
| TypeKind::F128
|
|
||||||
| TypeKind::F128PPC => Ok(other.clone()),
|
|
||||||
_ => Err(ErrorKind::TypesIncompatible(self.clone(), other.clone())),
|
_ => Err(ErrorKind::TypesIncompatible(self.clone(), other.clone())),
|
||||||
},
|
},
|
||||||
(TypeKind::Vague(Vague::Decimal), other) | (other, TypeKind::Vague(Vague::Decimal)) => match other {
|
(TypeKind::Vague(Vague::Decimal), other) | (other, TypeKind::Vague(Vague::Decimal)) => match other {
|
||||||
|
@ -431,7 +431,6 @@ impl Expression {
|
|||||||
params: (lhs_type.clone(), rhs_type.clone()),
|
params: (lhs_type.clone(), rhs_type.clone()),
|
||||||
operator: *op,
|
operator: *op,
|
||||||
});
|
});
|
||||||
// dbg!(&lhs_type, &rhs_type, &binops, &ret_ty, &expected_return_ty);
|
|
||||||
if let Some(binop) = binops
|
if let Some(binop) = binops
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|f| f.1.return_ty.narrow_into(&expected_return_ty).is_ok())
|
.filter(|f| f.1.return_ty.narrow_into(&expected_return_ty).is_ok())
|
||||||
|
@ -390,9 +390,6 @@ impl Expression {
|
|||||||
widened_rhs = widened_rhs.widen_into(&binop.hands.1);
|
widened_rhs = widened_rhs.widen_into(&binop.hands.1);
|
||||||
}
|
}
|
||||||
let binop_res = type_refs.from_binop(*op, &lhs_ref, &rhs_ref);
|
let binop_res = type_refs.from_binop(*op, &lhs_ref, &rhs_ref);
|
||||||
// dbg!(&return_ty);
|
|
||||||
// dbg!(&binop_res);
|
|
||||||
// dbg!(&lhs_ref, &rhs_ref, &binops, &widened_lhs, &widened_rhs);
|
|
||||||
lhs_ref.narrow(&type_refs.from_type(&widened_lhs).unwrap());
|
lhs_ref.narrow(&type_refs.from_type(&widened_lhs).unwrap());
|
||||||
rhs_ref.narrow(&type_refs.from_type(&widened_rhs).unwrap());
|
rhs_ref.narrow(&type_refs.from_type(&widened_rhs).unwrap());
|
||||||
*return_ty = binop_res.as_type();
|
*return_ty = binop_res.as_type();
|
||||||
|
@ -332,56 +332,21 @@ impl<'outer> ScopeTypeRefs<'outer> {
|
|||||||
.widen(self.types);
|
.widen(self.types);
|
||||||
self.narrow_to_type(&hint1, &ty)?;
|
self.narrow_to_type(&hint1, &ty)?;
|
||||||
let hint1_typeref = self.types.retrieve_typeref(*hint1.0.borrow()).unwrap();
|
let hint1_typeref = self.types.retrieve_typeref(*hint1.0.borrow()).unwrap();
|
||||||
let hint2_typeref = self.types.retrieve_typeref(*hint2.0.borrow()).unwrap();
|
|
||||||
|
|
||||||
match (&hint1_typeref, &hint2_typeref) {
|
|
||||||
(TypeRefKind::Direct(ret_ty), TypeRefKind::BinOp(op, lhs, rhs)) => {
|
|
||||||
let mut lhs_ref = self.from_type(&lhs).unwrap();
|
|
||||||
let mut rhs_ref = self.from_type(&rhs).unwrap();
|
|
||||||
let binops = self.available_binops(op, &mut lhs_ref, &mut rhs_ref);
|
|
||||||
let mut binops = binops
|
|
||||||
.iter()
|
|
||||||
.filter(|b| b.return_ty.narrow_into(ret_ty).is_ok())
|
|
||||||
.into_iter();
|
|
||||||
|
|
||||||
if let Some(binop) = binops.next() {
|
|
||||||
let mut lhs_widened = binop.hands.0.clone();
|
|
||||||
let mut rhs_widened = binop.hands.1.clone();
|
|
||||||
while let Some(binop) = binops.next() {
|
|
||||||
lhs_widened = lhs_widened.widen_into(&binop.hands.0);
|
|
||||||
rhs_widened = rhs_widened.widen_into(&binop.hands.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
lhs_ref.narrow(&self.from_type(&lhs_widened).unwrap());
|
|
||||||
rhs_ref.narrow(&self.from_type(&rhs_widened).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
for idx in self.types.type_refs.borrow_mut().iter_mut() {
|
for idx in self.types.type_refs.borrow_mut().iter_mut() {
|
||||||
match (&hint1_typeref, &hint2_typeref) {
|
match hint1_typeref {
|
||||||
(TypeRefKind::Direct(_), TypeRefKind::Direct(_)) => {
|
TypeRefKind::Direct(_) => {
|
||||||
if *idx == hint2.0 && idx != &hint1.0 {
|
if *idx == hint2.0 && idx != &hint1.0 {
|
||||||
*idx.borrow_mut() = *hint1.0.borrow();
|
*idx.borrow_mut() = *hint1.0.borrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(TypeRefKind::Direct(_), TypeRefKind::BinOp(..)) => {}
|
TypeRefKind::BinOp(_, _, _) => {
|
||||||
(TypeRefKind::BinOp(..), TypeRefKind::Direct(..)) => {
|
|
||||||
// TODO may not be good ?
|
// TODO may not be good ?
|
||||||
// if *idx == hint2.0 && idx != &hint1.0 {
|
// if *idx == hint2.0 && idx != &hint1.0 {
|
||||||
// *idx.borrow_mut() = *hint1.0.borrow();
|
// *idx.borrow_mut() = *hint1.0.borrow();
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
(TypeRefKind::BinOp(..), TypeRefKind::BinOp(..)) => {
|
|
||||||
// TODO may not be good ?
|
|
||||||
if *idx == hint2.0 && idx != &hint1.0 {
|
|
||||||
*idx.borrow_mut() = *hint1.0.borrow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(TypeRef(hint1.0.clone(), self))
|
Some(TypeRef(hint1.0.clone(), self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user