Compare commits
No commits in common. "469ce3ce77c5dbf1e48ed264ebbdf4a5cbd19835" and "63c54ae4da1dc4e3ea9423e897cc870047d3937a" have entirely different histories.
469ce3ce77
...
63c54ae4da
@ -1,6 +1,17 @@
|
||||
// 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 {
|
||||
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;
|
||||
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::Or(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
||||
Instr::XOr(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
||||
Instr::ICmp(_, lhs, rhs) => {
|
||||
let t = match_types(&lhs, &rhs, self)?;
|
||||
if t.category().comparable() || !t.category().integer() {
|
||||
@ -530,30 +528,6 @@ impl Builder {
|
||||
Instr::PtrToInt(instr, ty) => instr.cast_to(self, &ty).map(|_| ()),
|
||||
Instr::IntToPtr(instr, ty) => instr.cast_to(self, &ty).map(|_| ()),
|
||||
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),
|
||||
FRem(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),
|
||||
FCmp(_, _, _) => Ok(Type::Bool),
|
||||
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()),
|
||||
IntToPtr(instr, ty) => instr.cast_to(builder, ty).map(|_| 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),
|
||||
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 {
|
||||
|
@ -9,10 +9,10 @@ use crate::{
|
||||
CmpPredicate, Context, Instr, InstructionData, TerminatorKind,
|
||||
builder::*,
|
||||
debug_information::{
|
||||
DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocalVariable, DebugLocation,
|
||||
DebugLocationValue, DebugMetadata, DebugMetadataValue, DebugParamVariable, DebugPointerType, DebugPosition,
|
||||
DebugProgramValue, DebugRecordKind, DebugScopeValue, DebugStructType, DebugSubprogramType, DebugTypeData,
|
||||
DebugTypeHolder, DebugTypeValue,
|
||||
DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocalVariable,
|
||||
DebugLocation, DebugLocationValue, DebugMetadata, DebugMetadataValue, DebugParamVariable,
|
||||
DebugPointerType, DebugPosition, DebugProgramValue, DebugRecordKind, DebugScopeValue,
|
||||
DebugStructType, DebugSubprogramType, DebugTypeData, DebugTypeHolder, DebugTypeValue,
|
||||
},
|
||||
pad_adapter::PadAdapter,
|
||||
};
|
||||
@ -68,7 +68,11 @@ impl FunctionHolder {
|
||||
.map(|p| format!("{:?}", p))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
write!(f, "fn {}({}) -> {:?} ", self.data.name, params, self.data.ret)?;
|
||||
write!(
|
||||
f,
|
||||
"fn {}({}) -> {:?} ",
|
||||
self.data.name, params, self.data.ret
|
||||
)?;
|
||||
|
||||
writeln!(f, "{{")?;
|
||||
let mut state = Default::default();
|
||||
@ -112,7 +116,11 @@ impl BlockHolder {
|
||||
terminator.builder_fmt(&mut inner, builder, debug)?;
|
||||
}
|
||||
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(())
|
||||
@ -140,7 +148,11 @@ impl InstructionHolder {
|
||||
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(location) = self.data.location {
|
||||
writeln!(f, " ^ (At {}) ", debug.get_location(location))?;
|
||||
@ -176,9 +188,9 @@ impl TerminatorKind {
|
||||
impl DebugMetadataValue {
|
||||
fn hr(&self, debug: &DebugInformation) -> String {
|
||||
let kind = match debug.get_metadata(*self) {
|
||||
DebugMetadata::ParamVar(DebugParamVariable { name, arg_idx, ty, .. }) => {
|
||||
format!("param {} (idx {}) (type {:?}) ", name, arg_idx, ty)
|
||||
}
|
||||
DebugMetadata::ParamVar(DebugParamVariable {
|
||||
name, arg_idx, ty, ..
|
||||
}) => format!("param {} (idx {}) (type {:?}) ", name, arg_idx, ty),
|
||||
DebugMetadata::LocalVar(DebugLocalVariable { name, ty, .. }) => {
|
||||
format!("var {} (type {:?}) ", name, ty)
|
||||
}
|
||||
@ -241,11 +253,14 @@ impl Debug for FunctionHolder {
|
||||
impl Debug for BlockHolder {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let deleted = if self.data.deleted { " (deleted)" } else { "" };
|
||||
f.debug_tuple(&format!("{}[{:?}]{} ", &self.data.name, &self.value, deleted))
|
||||
.field(&self.instructions)
|
||||
.field(&self.data.terminator)
|
||||
.field(&self.data.terminator_location)
|
||||
.finish()
|
||||
f.debug_tuple(&format!(
|
||||
"{}[{:?}]{} ",
|
||||
&self.data.name, &self.value, deleted
|
||||
))
|
||||
.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 {
|
||||
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())?;
|
||||
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) => {
|
||||
write!(f, "{:?} to {:?} ({})", instr_val, ty, self.default_name())
|
||||
}
|
||||
@ -387,11 +408,6 @@ impl Debug for Instr {
|
||||
Instr::BitCast(instr_val, ty) => {
|
||||
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!(
|
||||
f,
|
||||
"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::IntToPtr(_, _) => "inttoptr",
|
||||
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),
|
||||
/// Get the remainder from two floats
|
||||
FRem(InstructionValue, InstructionValue),
|
||||
|
||||
And(InstructionValue, InstructionValue),
|
||||
Or(InstructionValue, InstructionValue),
|
||||
XOr(InstructionValue, InstructionValue),
|
||||
ShiftRightLogical(InstructionValue, InstructionValue),
|
||||
ShiftRightArithmetic(InstructionValue, InstructionValue),
|
||||
ShiftLeft(InstructionValue, InstructionValue),
|
||||
|
||||
Phi(Vec<InstructionValue>),
|
||||
|
||||
Alloca(Type),
|
||||
|
@ -88,10 +88,6 @@ pub enum Token {
|
||||
LessThan,
|
||||
/// `&`
|
||||
Et,
|
||||
/// `|`
|
||||
Pipe,
|
||||
/// `^`
|
||||
Hat,
|
||||
/// `!`
|
||||
Exclamation,
|
||||
|
||||
@ -178,8 +174,6 @@ impl ToString for Token {
|
||||
Token::GreaterThan => String::from('>'),
|
||||
Token::LessThan => String::from('<'),
|
||||
Token::Et => String::from('&'),
|
||||
Token::Pipe => String::from('|'),
|
||||
Token::Hat => String::from('^'),
|
||||
Token::Exclamation => String::from('!'),
|
||||
Token::ParenOpen => 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::LessThan,
|
||||
'&' => Token::Et,
|
||||
'|' => Token::Pipe,
|
||||
'^' => Token::Hat,
|
||||
'!' => Token::Exclamation,
|
||||
'(' => Token::ParenOpen,
|
||||
')' => Token::ParenClose,
|
||||
|
@ -116,14 +116,7 @@ pub enum BinaryOperator {
|
||||
Div,
|
||||
Mod,
|
||||
|
||||
BitshiftRight,
|
||||
BitshiftLeft,
|
||||
|
||||
And,
|
||||
Or,
|
||||
Xor,
|
||||
BWAnd,
|
||||
BWOr,
|
||||
LT,
|
||||
LE,
|
||||
GT,
|
||||
@ -133,7 +126,7 @@ pub enum BinaryOperator {
|
||||
}
|
||||
|
||||
impl BinaryOperator {
|
||||
pub fn get_precedence(&self) -> u8 {
|
||||
pub fn get_precedence(&self) -> i8 {
|
||||
use BinaryOperator::*;
|
||||
match &self {
|
||||
Minus => 5,
|
||||
@ -141,20 +134,13 @@ impl BinaryOperator {
|
||||
Mult => 15,
|
||||
Div => 20,
|
||||
Mod => 20,
|
||||
BWAnd => 90,
|
||||
BWOr => 90,
|
||||
BWXor => 90,
|
||||
BitshiftLeft => 100,
|
||||
BitshiftRight => 100,
|
||||
And => 150,
|
||||
Or => 150,
|
||||
Xor => 150,
|
||||
LT => 150,
|
||||
LE => 150,
|
||||
GT => 150,
|
||||
GE => 150,
|
||||
EQ => 150,
|
||||
NE => 150,
|
||||
And => 100,
|
||||
LT => 100,
|
||||
LE => 100,
|
||||
GT => 100,
|
||||
GE => 100,
|
||||
EQ => 100,
|
||||
NE => 100,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -488,10 +488,6 @@ impl Parse for BinaryOperator {
|
||||
stream.next();
|
||||
BinaryOperator::And
|
||||
}
|
||||
(Some(Token::Pipe), Some(Token::Pipe)) => {
|
||||
stream.next();
|
||||
BinaryOperator::Or
|
||||
}
|
||||
(Some(Token::LessThan), Some(Token::Equals)) => {
|
||||
stream.next();
|
||||
BinaryOperator::LE
|
||||
@ -508,18 +504,6 @@ impl Parse for BinaryOperator {
|
||||
stream.next();
|
||||
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::GreaterThan), _) => BinaryOperator::GT,
|
||||
|
@ -446,21 +446,15 @@ impl ast::BinaryOperator {
|
||||
ast::BinaryOperator::Add => mir::BinaryOperator::Add,
|
||||
ast::BinaryOperator::Minus => mir::BinaryOperator::Minus,
|
||||
ast::BinaryOperator::Mult => mir::BinaryOperator::Mult,
|
||||
ast::BinaryOperator::And => mir::BinaryOperator::And,
|
||||
ast::BinaryOperator::Div => mir::BinaryOperator::Div,
|
||||
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::LE => mir::BinaryOperator::Cmp(mir::CmpOperator::LE),
|
||||
ast::BinaryOperator::GT => mir::BinaryOperator::Cmp(mir::CmpOperator::GT),
|
||||
ast::BinaryOperator::GE => mir::BinaryOperator::Cmp(mir::CmpOperator::GE),
|
||||
ast::BinaryOperator::EQ => mir::BinaryOperator::Cmp(mir::CmpOperator::EQ),
|
||||
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 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
|
||||
where
|
||||
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| {
|
||||
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]) {
|
||||
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| {
|
||||
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
|
||||
}
|
||||
|
@ -885,30 +885,6 @@ impl mir::Expression {
|
||||
.maybe_location(&mut scope.block, location);
|
||||
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(
|
||||
StackValueKind::Immutable(
|
||||
|
@ -352,12 +352,6 @@ impl Display for BinaryOperator {
|
||||
BinaryOperator::Cmp(op) => Display::fmt(op, f),
|
||||
BinaryOperator::Div => 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 {
|
||||
/// 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 {
|
||||
match self {
|
||||
TypeKind::Bool => false,
|
||||
@ -206,12 +240,6 @@ impl BinaryOperator {
|
||||
CmpOperator::EQ => 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)
|
||||
}
|
||||
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::If(_) => None,
|
||||
|
@ -222,12 +222,6 @@ pub enum BinaryOperator {
|
||||
Div,
|
||||
Mod,
|
||||
And,
|
||||
Or,
|
||||
Xor,
|
||||
BitOr,
|
||||
BitAnd,
|
||||
BitshiftRight,
|
||||
BitshiftLeft,
|
||||
Cmp(CmpOperator),
|
||||
}
|
||||
|
||||
|
@ -135,14 +135,7 @@ impl TypeKind {
|
||||
| TypeKind::U16
|
||||
| TypeKind::U32
|
||||
| TypeKind::U64
|
||||
| TypeKind::U128
|
||||
| TypeKind::F16
|
||||
| TypeKind::F32B
|
||||
| TypeKind::F32
|
||||
| TypeKind::F64
|
||||
| TypeKind::F80
|
||||
| TypeKind::F128
|
||||
| TypeKind::F128PPC => Ok(other.clone()),
|
||||
| TypeKind::U128 => Ok(other.clone()),
|
||||
_ => Err(ErrorKind::TypesIncompatible(self.clone(), other.clone())),
|
||||
},
|
||||
(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()),
|
||||
operator: *op,
|
||||
});
|
||||
// dbg!(&lhs_type, &rhs_type, &binops, &ret_ty, &expected_return_ty);
|
||||
if let Some(binop) = binops
|
||||
.iter()
|
||||
.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);
|
||||
}
|
||||
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());
|
||||
rhs_ref.narrow(&type_refs.from_type(&widened_rhs).unwrap());
|
||||
*return_ty = binop_res.as_type();
|
||||
|
@ -332,56 +332,21 @@ impl<'outer> ScopeTypeRefs<'outer> {
|
||||
.widen(self.types);
|
||||
self.narrow_to_type(&hint1, &ty)?;
|
||||
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() {
|
||||
match (&hint1_typeref, &hint2_typeref) {
|
||||
(TypeRefKind::Direct(_), TypeRefKind::Direct(_)) => {
|
||||
match hint1_typeref {
|
||||
TypeRefKind::Direct(_) => {
|
||||
if *idx == hint2.0 && idx != &hint1.0 {
|
||||
*idx.borrow_mut() = *hint1.0.borrow();
|
||||
}
|
||||
}
|
||||
(TypeRefKind::Direct(_), TypeRefKind::BinOp(..)) => {}
|
||||
(TypeRefKind::BinOp(..), TypeRefKind::Direct(..)) => {
|
||||
TypeRefKind::BinOp(_, _, _) => {
|
||||
// TODO may not be good ?
|
||||
// if *idx == hint2.0 && idx != &hint1.0 {
|
||||
// *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))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user