diff --git a/README.md b/README.md index e760d21..53e22f8 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ Currently missing big features (TODOs) are: - ~~Pointers~~ (DONE) - ~~Unary operators~~ - Floats +- Type casting - Loops - Debug Information (PARTIALLY DONE) - Ability to specify types in literals and variable definitions diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index 8352e10..f045ba0 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -1034,6 +1034,13 @@ impl ConstValue { into_cstring(val).as_ptr(), c"string".as_ptr(), ), + ConstValue::F16(val) => LLVMConstReal(t, *val as f64), + ConstValue::F32B(val) => LLVMConstReal(t, *val as f64), + ConstValue::F32(val) => LLVMConstReal(t, *val as f64), + ConstValue::F64(val) => LLVMConstReal(t, *val as f64), + ConstValue::F80(val) => LLVMConstReal(t, *val as f64), + ConstValue::F128(val) => LLVMConstReal(t, *val as f64), + ConstValue::F128PPC(val) => LLVMConstReal(t, *val as f64), } } } @@ -1058,6 +1065,13 @@ impl Type { Ptr(ty) => LLVMPointerType(ty.as_llvm(context, typemap), 0), CustomType(struct_ty) => *typemap.get(struct_ty).unwrap(), Array(r#type, len) => LLVMArrayType2(r#type.as_llvm(context, typemap), *len), + F16 => LLVMHalfTypeInContext(context), + F32 => LLVMFloatTypeInContext(context), + F32B => LLVMBFloatTypeInContext(context), + F64 => LLVMDoubleTypeInContext(context), + F80 => LLVMX86FP80TypeInContext(context), + F128 => LLVMFP128TypeInContext(context), + F128PPC => LLVMPPCFP128TypeInContext(context), } } } diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 91244d5..0c86985 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -307,7 +307,7 @@ pub enum CmpPredicate { NE, } -#[derive(Clone, Hash)] +#[derive(Clone)] pub enum Instr { Param(usize), Constant(ConstValue), @@ -344,6 +344,13 @@ pub enum Type { U32, U64, U128, + F16, + F32B, + F32, + F64, + F80, + F128, + F128PPC, Bool, Void, CustomType(TypeValue), @@ -351,7 +358,7 @@ pub enum Type { Ptr(Box), } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone)] pub enum ConstValue { I8(i8), I16(i16), @@ -365,6 +372,13 @@ pub enum ConstValue { U128(u128), Bool(bool), StringPtr(String), + F16(f32), + F32B(f32), + F32(f32), + F64(f64), + F80(f64), + F128(f64), + F128PPC(f64), } #[derive(Clone, Hash)] @@ -473,6 +487,13 @@ impl ConstValue { ConstValue::U128(_) => U128, ConstValue::StringPtr(_) => Ptr(Box::new(I8)), ConstValue::Bool(_) => Bool, + ConstValue::F16(_) => todo!(), + ConstValue::F32B(_) => todo!(), + ConstValue::F32(_) => todo!(), + ConstValue::F64(_) => todo!(), + ConstValue::F80(_) => todo!(), + ConstValue::F128(_) => todo!(), + ConstValue::F128PPC(_) => todo!(), } } } @@ -495,6 +516,13 @@ impl Type { Type::Ptr(_) => false, Type::CustomType(_) => false, Type::Array(_, _) => false, + Type::F16 => true, + Type::F32B => true, + Type::F32 => true, + Type::F64 => true, + Type::F80 => true, + Type::F128 => true, + Type::F128PPC => true, } } @@ -515,6 +543,13 @@ impl Type { Type::Ptr(_) => false, Type::CustomType(_) => false, Type::Array(_, _) => false, + Type::F16 => true, + Type::F32B => true, + Type::F32 => true, + Type::F64 => true, + Type::F80 => true, + Type::F128 => true, + Type::F128PPC => true, } } } diff --git a/reid/src/ast/mod.rs b/reid/src/ast/mod.rs index 99b31da..d78a134 100644 --- a/reid/src/ast/mod.rs +++ b/reid/src/ast/mod.rs @@ -25,7 +25,7 @@ pub enum TypeKind { U64, U128, F16, - F16B, + F32B, F32, F64, F128, diff --git a/reid/src/ast/parse.rs b/reid/src/ast/parse.rs index 2810707..3765d68 100644 --- a/reid/src/ast/parse.rs +++ b/reid/src/ast/parse.rs @@ -54,7 +54,7 @@ impl Parse for Type { "u64" => TypeKind::U64, "u128" => TypeKind::U128, "f16" => TypeKind::F16, - "f16b" => TypeKind::F16B, + "f32b" => TypeKind::F32B, "f32" => TypeKind::F32, "f64" => TypeKind::F64, "f80" => TypeKind::F80, diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index cd1c29b..7b18b57 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -285,7 +285,7 @@ impl ast::Literal { ast::Literal::Integer(v) => mir::Literal::Vague(mir::VagueLiteral::Number(*v)), ast::Literal::Bool(v) => mir::Literal::Bool(*v), ast::Literal::String(val) => mir::Literal::String(val.clone()), - ast::Literal::Decimal(_) => todo!(), + ast::Literal::Decimal(v) => mir::Literal::Vague(mir::VagueLiteral::Decimal(*v)), } } } @@ -315,13 +315,13 @@ impl From for mir::TypeKind { ast::TypeKind::Ptr(type_kind) => { mir::TypeKind::UserPtr(Box::new(mir::TypeKind::from(*type_kind.clone()))) } - ast::TypeKind::F16 => todo!(), - ast::TypeKind::F16B => todo!(), - ast::TypeKind::F32 => todo!(), - ast::TypeKind::F64 => todo!(), - ast::TypeKind::F128 => todo!(), - ast::TypeKind::F80 => todo!(), - ast::TypeKind::F128PPC => todo!(), + ast::TypeKind::F16 => mir::TypeKind::F16, + ast::TypeKind::F32B => mir::TypeKind::F32B, + ast::TypeKind::F32 => mir::TypeKind::F32, + ast::TypeKind::F64 => mir::TypeKind::F64, + ast::TypeKind::F80 => mir::TypeKind::F80, + ast::TypeKind::F128 => mir::TypeKind::F128, + ast::TypeKind::F128PPC => mir::TypeKind::F128PPC, } } } diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index 3358ea2..ac5c719 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -1172,6 +1172,14 @@ impl mir::Literal { mir::Literal::Bool(val) => ConstValue::Bool(val), mir::Literal::String(val) => ConstValue::StringPtr(val.clone()), mir::Literal::Vague(VagueLiteral::Number(val)) => ConstValue::I32(val as i32), + mir::Literal::Vague(VagueLiteral::Decimal(val)) => ConstValue::F32(val as f32), + mir::Literal::F16(val) => ConstValue::F16(val), + mir::Literal::F32B(val) => ConstValue::F32B(val), + mir::Literal::F32(val) => ConstValue::F32(val), + mir::Literal::F64(val) => ConstValue::F64(val), + mir::Literal::F80(val) => ConstValue::F80(val), + mir::Literal::F128(val) => ConstValue::F128(val), + mir::Literal::F128PPC(val) => ConstValue::F128PPC(val), }) } } @@ -1194,6 +1202,13 @@ impl TypeKind { TypeKind::U64 => Type::U64, TypeKind::U128 => Type::U128, TypeKind::Bool => Type::Bool, + TypeKind::F16 => Type::F16, + TypeKind::F32B => Type::F32B, + TypeKind::F32 => Type::F32, + TypeKind::F64 => Type::F64, + TypeKind::F128 => Type::F128, + TypeKind::F80 => Type::F80, + TypeKind::F128PPC => Type::F128PPC, TypeKind::StringPtr => Type::Ptr(Box::new(Type::I8)), TypeKind::Array(elem_t, len) => { Type::Array(Box::new(elem_t.get_type(type_vals, typedefs)), *len) diff --git a/reid/src/error_raporting.rs b/reid/src/error_raporting.rs index bd54df5..ef379b5 100644 --- a/reid/src/error_raporting.rs +++ b/reid/src/error_raporting.rs @@ -18,7 +18,7 @@ fn label(text: &str) -> &str { "" } -#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)] +#[derive(thiserror::Error, Debug, Clone, PartialEq)] pub enum ErrorKind { #[error("{}{}", label("(Lexing) "), .0.kind)] LexerError(#[from] mir::pass::Error), @@ -62,12 +62,6 @@ impl PartialOrd for ErrorKind { } } -impl Ord for ErrorKind { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.get_meta().cmp(&other.get_meta()) - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct Module { pub name: String, @@ -112,7 +106,7 @@ impl ModuleMap { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq)] pub struct ReidError { map: ModuleMap, errors: Vec, @@ -171,37 +165,38 @@ impl std::error::Error for ReidError {} impl std::fmt::Display for ReidError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut sorted_errors = self.errors.clone(); - sorted_errors.sort_by(|a, b| a.cmp(&b)); + sorted_errors.sort_by(|a, b| a.partial_cmp(&b).unwrap_or(std::cmp::Ordering::Equal)); sorted_errors.dedup(); let mut curr_module = None; for error in sorted_errors { let meta = error.get_meta(); - let module = self.map.module(&meta.source_module_id).unwrap(); - let position = if let Some(tokens) = &module.tokens { - let range_tokens = meta.range.into_tokens(&tokens); + let module = self.map.module(&meta.source_module_id); + let position = if let Some(module) = module { + if let Some(tokens) = &module.tokens { + let range_tokens = meta.range.into_tokens(&tokens); - get_position(&range_tokens).or(meta.position.map(|p| (p, p))) - } else if let Some(position) = meta.position { - Some((position, position)) + get_position(&range_tokens).or(meta.position.map(|p| (p, p))) + } else if let Some(position) = meta.position { + Some((position, position)) + } else { + None + } } else { None }; if curr_module != Some(meta.source_module_id) { curr_module = Some(meta.source_module_id); - writeln!( - f, - "Errors in module {}:", - color_err(format!( - "{}", - self.map - .module_map - .get(&meta.source_module_id) - .unwrap() - .name - ))? - )?; + if let Some(module) = self.map.module_map.get(&meta.source_module_id) { + writeln!( + f, + "Errors in module {}:", + color_err(format!("{}", module.name))? + )?; + } else { + writeln!(f, "Errors detected: {}", color_err("in general")?)?; + } } writeln!(f)?; write!(f, " Error: ")?; @@ -214,7 +209,9 @@ impl std::fmt::Display for ReidError { .map(|p| fmt_positions(p)) .unwrap_or(String::from("{unknown}")), )?; - if let (Some(position), Some(source)) = (position, &module.source) { + if let (Some(position), Some(source)) = + (position, &module.and_then(|m| m.source.clone())) + { writeln!(f, "{}", fmt_lines(source, position, 6)?)?; } } diff --git a/reid/src/mir/fmt.rs b/reid/src/mir/fmt.rs index 3048c90..7352f9a 100644 --- a/reid/src/mir/fmt.rs +++ b/reid/src/mir/fmt.rs @@ -261,6 +261,13 @@ impl Display for Literal { Literal::Bool(val) => write!(f, "{}", val), Literal::String(val) => std::fmt::Debug::fmt(val, f), Literal::Vague(val) => val.fmt(f), + Literal::F16(val) => write!(f, "{}f16", val), + Literal::F32B(val) => write!(f, "{}f16b", val), + Literal::F32(val) => write!(f, "{}f32", val), + Literal::F64(val) => write!(f, "{}f64", val), + Literal::F80(val) => write!(f, "{}f80", val), + Literal::F128(val) => write!(f, "{}f128", val), + Literal::F128PPC(val) => write!(f, "{}f128ppc", val), } } } @@ -354,6 +361,13 @@ impl Display for TypeKind { Display::fmt(type_kind, f) } TypeKind::Vague(vague_type) => Display::fmt(vague_type, f), + TypeKind::F16 => write!(f, "f16"), + TypeKind::F32B => write!(f, "f16b"), + TypeKind::F32 => write!(f, "f32"), + TypeKind::F64 => write!(f, "f64"), + TypeKind::F128 => write!(f, "f128"), + TypeKind::F80 => write!(f, "f80"), + TypeKind::F128PPC => write!(f, "f128ppc"), } } } @@ -363,14 +377,16 @@ impl Display for VagueType { if f.alternate() { match self { VagueType::Unknown => write!(f, "Unknown"), - VagueType::Number => write!(f, "Number"), + VagueType::Integer => write!(f, "Number"), VagueType::TypeRef(id) => write!(f, "TypeRef({0})", id), + VagueType::Decimal => write!(f, "Decimal"), } } else { match self { VagueType::Unknown => write!(f, "{{unknown}}"), - VagueType::Number => write!(f, "Number"), + VagueType::Integer => write!(f, "Number"), VagueType::TypeRef(_) => write!(f, "{{unknown}}"), + VagueType::Decimal => write!(f, "Decimal"), } } } diff --git a/reid/src/mir/implement.rs b/reid/src/mir/implement.rs index 43fa900..fb082b5 100644 --- a/reid/src/mir/implement.rs +++ b/reid/src/mir/implement.rs @@ -44,12 +44,19 @@ impl TypeKind { TypeKind::U128 => false, TypeKind::Void => false, TypeKind::StringPtr => false, - TypeKind::Array(type_kind, len) => false, + TypeKind::Array(_, _) => false, TypeKind::CustomType(_) => false, TypeKind::CodegenPtr(_) => false, TypeKind::Vague(_) => false, TypeKind::Borrow(_, _) => false, TypeKind::UserPtr(_) => false, + TypeKind::F16 => true, + TypeKind::F32B => true, + TypeKind::F32 => true, + TypeKind::F64 => true, + TypeKind::F128 => true, + TypeKind::F80 => true, + TypeKind::F128PPC => true, } } @@ -74,6 +81,13 @@ impl TypeKind { TypeKind::Vague(_) => panic!("Tried to sizeof a vague type!"), TypeKind::Borrow(_, _) => 64, TypeKind::UserPtr(_) => 64, + TypeKind::F16 => 16, + TypeKind::F32B => 16, + TypeKind::F32 => 32, + TypeKind::F64 => 64, + TypeKind::F128 => 128, + TypeKind::F80 => 80, + TypeKind::F128PPC => 128, } } @@ -98,6 +112,13 @@ impl TypeKind { TypeKind::Vague(_) => panic!("Tried to sizeof a vague type!"), TypeKind::Borrow(_, _) => 64, TypeKind::UserPtr(_) => 64, + TypeKind::F16 => 16, + TypeKind::F32B => 16, + TypeKind::F32 => 32, + TypeKind::F64 => 64, + TypeKind::F128 => 128, + TypeKind::F80 => 80, + TypeKind::F128PPC => 128, } } @@ -379,8 +400,9 @@ impl TypeKind { match self { TypeKind::Vague(vague_type) => match &vague_type { Vague::Unknown => Err(ErrorKind::TypeIsVague(*vague_type)), - Vague::Number => Ok(TypeKind::I32), + Vague::Integer => Ok(TypeKind::I32), Vague::TypeRef(_) => panic!("Hinted default!"), + VagueType::Decimal => Ok(TypeKind::F32), }, _ => Ok(self.clone()), } @@ -418,10 +440,10 @@ impl Collapsable for TypeKind { } match (self, other) { - (TypeKind::Vague(Vague::Number), other) | (other, TypeKind::Vague(Vague::Number)) => { + (TypeKind::Vague(Vague::Integer), other) | (other, TypeKind::Vague(Vague::Integer)) => { match other { - TypeKind::Vague(Vague::Unknown) => Ok(TypeKind::Vague(Vague::Number)), - TypeKind::Vague(Vague::Number) => Ok(TypeKind::Vague(Vague::Number)), + TypeKind::Vague(Vague::Unknown) => Ok(TypeKind::Vague(Vague::Integer)), + TypeKind::Vague(Vague::Integer) => Ok(TypeKind::Vague(Vague::Integer)), TypeKind::I8 | TypeKind::I16 | TypeKind::I32 @@ -474,6 +496,14 @@ impl Literal { Literal::Bool(_) => None, Literal::String(_) => None, Literal::Vague(VagueLiteral::Number(val)) => Some(*val as i128), + Literal::Vague(VagueLiteral::Decimal(_)) => None, + Literal::F16(_) => None, + Literal::F32B(_) => None, + Literal::F32(_) => None, + Literal::F64(_) => None, + Literal::F80(_) => None, + Literal::F128(_) => None, + Literal::F128PPC(_) => None, } } } diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index cb08ac3..af21d79 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -91,6 +91,13 @@ pub enum TypeKind { U64, U128, Void, + F16, + F32B, + F32, + F64, + F128, + F80, + F128PPC, StringPtr, Array(Box, u64), CustomType(String), @@ -103,7 +110,8 @@ pub enum TypeKind { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum VagueType { Unknown, - Number, + Integer, + Decimal, TypeRef(usize), } @@ -133,7 +141,7 @@ impl TypeKind { } } -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Clone, PartialEq, PartialOrd)] pub enum Literal { I8(i8), I16(i16), @@ -145,14 +153,22 @@ pub enum Literal { U32(u32), U64(u64), U128(u128), + F16(f32), + F32B(f32), + F32(f32), + F64(f64), + F80(f64), + F128(f64), + F128PPC(f64), Bool(bool), String(String), Vague(VagueLiteral), } -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] pub enum VagueLiteral { Number(u64), + Decimal(f64), } impl Literal { @@ -170,7 +186,15 @@ impl Literal { Literal::U128(_) => TypeKind::U128, Literal::Bool(_) => TypeKind::Bool, Literal::String(_) => TypeKind::StringPtr, - Literal::Vague(VagueLiteral::Number(_)) => TypeKind::Vague(VagueType::Number), + Literal::Vague(VagueLiteral::Number(_)) => TypeKind::Vague(VagueType::Integer), + Literal::Vague(VagueLiteral::Decimal(_)) => TypeKind::Vague(VagueType::Decimal), + Literal::F16(_) => TypeKind::F16, + Literal::F32B(_) => TypeKind::F32B, + Literal::F32(_) => TypeKind::F32, + Literal::F64(_) => TypeKind::F64, + Literal::F80(_) => TypeKind::F80, + Literal::F128(_) => TypeKind::F128, + Literal::F128PPC(_) => TypeKind::F128PPC, } } } @@ -178,7 +202,8 @@ impl Literal { impl VagueLiteral { pub fn as_type(self: &VagueLiteral) -> VagueType { match self { - VagueLiteral::Number(_) => VagueType::Number, + VagueLiteral::Number(_) => VagueType::Integer, + VagueLiteral::Decimal(_) => VagueType::Decimal, } } } diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index a257973..03f707a 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -11,7 +11,7 @@ use super::{ typerefs::TypeRefs, }; -#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[derive(thiserror::Error, Debug, Clone, PartialEq, PartialOrd)] pub enum ErrorKind { #[error("NULL error, should never occur!")] Null,