From 46560d85410001b26fac3210d73ba0749d35ade7 Mon Sep 17 00:00:00 2001 From: sofia Date: Tue, 8 Jul 2025 23:47:44 +0300 Subject: [PATCH] Add all types u8 -> i128 and fix signedness in icmp --- reid-llvm-lib/src/builder.rs | 28 +++++++++++-- reid-llvm-lib/src/compile.rs | 32 ++++++++++----- reid-llvm-lib/src/lib.rs | 19 ++++++++- reid/examples/reid/fibonacci.reid | 4 +- reid/src/ast/mod.rs | 10 +++++ reid/src/ast/parse.rs | 10 +++++ reid/src/ast/process.rs | 10 +++++ reid/src/codegen.rs | 20 +++++++++- reid/src/mir/mod.rs | 66 +++++++++++++++++++++++++++---- reid/src/mir/typecheck.rs | 23 +++++++++-- 10 files changed, 191 insertions(+), 31 deletions(-) diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index c56e450..d995486 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -260,9 +260,17 @@ impl ConstValue { pub fn get_type(&self) -> Type { use Type::*; match self { - ConstValue::I32(_) => I32, + ConstValue::I8(_) => I8, ConstValue::I16(_) => I16, + ConstValue::I32(_) => I32, + ConstValue::I64(_) => I64, + ConstValue::I128(_) => I128, + ConstValue::U8(_) => U8, + ConstValue::U16(_) => U16, ConstValue::U32(_) => U32, + ConstValue::U64(_) => U64, + ConstValue::U128(_) => U128, + ConstValue::Bool(_) => Bool, } } } @@ -270,9 +278,16 @@ impl ConstValue { impl Type { pub fn comparable(&self) -> bool { match self { - Type::I32 => true, + Type::I8 => true, Type::I16 => true, + Type::I32 => true, + Type::I64 => true, + Type::I128 => true, + Type::U8 => true, + Type::U16 => true, Type::U32 => true, + Type::U64 => true, + Type::U128 => true, Type::Bool => true, Type::Void => false, } @@ -280,9 +295,16 @@ impl Type { pub fn signed(&self) -> bool { match self { - Type::I32 => true, + Type::I8 => true, Type::I16 => true, + Type::I32 => true, + Type::I64 => true, + Type::I128 => true, + Type::U8 => false, + Type::U16 => false, Type::U32 => false, + Type::U64 => false, + Type::U128 => false, Type::Bool => false, Type::Void => false, } diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index be78af0..c0c622d 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -264,12 +264,13 @@ impl InstructionHolder { LLVMBuildSub(module.builder_ref, lhs_val, rhs_val, c"sub".as_ptr()) } ICmp(pred, lhs, rhs) => { - let lhs_val = module.values.get(&lhs).unwrap().value_ref; + let lhs = module.values.get(&lhs).unwrap(); let rhs_val = module.values.get(&rhs).unwrap().value_ref; LLVMBuildICmp( module.builder_ref, - pred.as_llvm(_ty.signed()), - lhs_val, + // Signedness from LHS + pred.as_llvm(lhs._ty.signed()), + lhs.value_ref, rhs_val, c"icmp".as_ptr(), ) @@ -370,9 +371,17 @@ impl ConstValue { unsafe { let t = self.get_type().as_llvm(context); match *self { - ConstValue::I32(val) => LLVMConstInt(t, val as u64, 1), + ConstValue::Bool(val) => LLVMConstInt(t, val as u64, 1), + ConstValue::I8(val) => LLVMConstInt(t, val as u64, 1), ConstValue::I16(val) => LLVMConstInt(t, val as u64, 1), - ConstValue::U32(val) => LLVMConstInt(t, val as u64, 0), + ConstValue::I32(val) => LLVMConstInt(t, val as u64, 1), + ConstValue::I64(val) => LLVMConstInt(t, val as u64, 1), + ConstValue::I128(val) => LLVMConstInt(t, val as u64, 1), + ConstValue::U8(val) => LLVMConstInt(t, val as u64, 1), + ConstValue::U16(val) => LLVMConstInt(t, val as u64, 1), + ConstValue::U32(val) => LLVMConstInt(t, val as u64, 1), + ConstValue::U64(val) => LLVMConstInt(t, val as u64, 1), + ConstValue::U128(val) => LLVMConstInt(t, val as u64, 1), } } } @@ -380,13 +389,16 @@ impl ConstValue { impl Type { fn as_llvm(&self, context: LLVMContextRef) -> LLVMTypeRef { + use Type::*; unsafe { match self { - Type::I32 => LLVMInt32TypeInContext(context), - Type::I16 => LLVMInt16TypeInContext(context), - Type::U32 => LLVMInt32TypeInContext(context), - Type::Bool => LLVMInt1TypeInContext(context), - Type::Void => LLVMVoidType(), + I8 | U8 => LLVMInt8TypeInContext(context), + I16 | U16 => LLVMInt16TypeInContext(context), + I32 | U32 => LLVMInt32TypeInContext(context), + I64 | U64 => LLVMInt64TypeInContext(context), + I128 | U128 => LLVMInt128TypeInContext(context), + Bool => LLVMInt1TypeInContext(context), + Void => LLVMVoidType(), } } } diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index aefbe88..16c81a9 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -158,18 +158,33 @@ pub enum InstructionKind { #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] pub enum Type { - I32, + I8, I16, + I32, + I64, + I128, + U8, + U16, U32, + U64, + U128, Bool, Void, } #[derive(Debug, Clone, Hash)] pub enum ConstValue { - I32(i32), + I8(i8), I16(i16), + I32(i32), + I64(i64), + I128(i128), + U8(u8), + U16(u16), U32(u32), + U64(u64), + U128(u128), + Bool(bool), } #[derive(Clone, Hash)] diff --git a/reid/examples/reid/fibonacci.reid b/reid/examples/reid/fibonacci.reid index 7fc98c8..84625c7 100644 --- a/reid/examples/reid/fibonacci.reid +++ b/reid/examples/reid/fibonacci.reid @@ -1,11 +1,11 @@ // Main -fn main() -> i32 { +fn main() -> u8 { let a = fibonacci(3); return a; } // Fibonacci -fn fibonacci(value: i32) -> i32 { +fn fibonacci(value: u8) -> u8 { if value < 3 { return 1; } diff --git a/reid/src/ast/mod.rs b/reid/src/ast/mod.rs index 7a8265e..6bd368f 100644 --- a/reid/src/ast/mod.rs +++ b/reid/src/ast/mod.rs @@ -8,7 +8,17 @@ pub struct Type(pub TypeKind, pub TokenRange); #[derive(Debug, Clone, Copy)] pub enum TypeKind { + Bool, + I8, + I16, I32, + I64, + I128, + U8, + U16, + U32, + U64, + U128, } #[derive(Debug, Clone)] diff --git a/reid/src/ast/parse.rs b/reid/src/ast/parse.rs index 9c16235..1da3c49 100644 --- a/reid/src/ast/parse.rs +++ b/reid/src/ast/parse.rs @@ -15,7 +15,17 @@ impl Parse for Type { fn parse(mut stream: TokenStream) -> Result { let kind = if let Some(Token::Identifier(ident)) = stream.next() { Ok(match &*ident { + "bool" => TypeKind::Bool, + "i8" => TypeKind::I8, + "i16" => TypeKind::I16, "i32" => TypeKind::I32, + "i64" => TypeKind::I64, + "i128" => TypeKind::I128, + "u8" => TypeKind::U8, + "u16" => TypeKind::U16, + "u32" => TypeKind::U32, + "u64" => TypeKind::U64, + "u128" => TypeKind::U128, _ => panic!("asd"), }) } else { diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 7009ff2..8277d17 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -168,7 +168,17 @@ impl ast::Literal { impl From for mir::TypeKind { fn from(value: ast::TypeKind) -> Self { match value { + ast::TypeKind::Bool => mir::TypeKind::Bool, + ast::TypeKind::I8 => mir::TypeKind::I8, + ast::TypeKind::I16 => mir::TypeKind::I16, ast::TypeKind::I32 => mir::TypeKind::I32, + ast::TypeKind::I64 => mir::TypeKind::I64, + ast::TypeKind::I128 => mir::TypeKind::I128, + ast::TypeKind::U8 => mir::TypeKind::U8, + ast::TypeKind::U16 => mir::TypeKind::U16, + ast::TypeKind::U32 => mir::TypeKind::U32, + ast::TypeKind::U64 => mir::TypeKind::U64, + ast::TypeKind::U128 => mir::TypeKind::U128, } } } diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index b49b954..00a03e7 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -323,8 +323,16 @@ impl mir::Literal { pub fn as_const_kind(&self) -> InstructionKind { InstructionKind::Constant(match *self { - mir::Literal::I32(val) => ConstValue::I32(val), + mir::Literal::I8(val) => ConstValue::I8(val), mir::Literal::I16(val) => ConstValue::I16(val), + mir::Literal::I32(val) => ConstValue::I32(val), + mir::Literal::I64(val) => ConstValue::I64(val), + mir::Literal::I128(val) => ConstValue::I128(val), + mir::Literal::U8(val) => ConstValue::U8(val), + mir::Literal::U16(val) => ConstValue::U16(val), + mir::Literal::U32(val) => ConstValue::U32(val), + mir::Literal::U64(val) => ConstValue::U64(val), + mir::Literal::U128(val) => ConstValue::U128(val), mir::Literal::Vague(_) => panic!("Got vague literal!"), }) } @@ -333,8 +341,16 @@ impl mir::Literal { impl TypeKind { fn get_type(&self) -> Type { match &self { - TypeKind::I32 => Type::I32, + TypeKind::I8 => Type::I8, TypeKind::I16 => Type::I16, + TypeKind::I32 => Type::I32, + TypeKind::I64 => Type::I64, + TypeKind::I128 => Type::I128, + TypeKind::U8 => Type::U8, + TypeKind::U16 => Type::U16, + TypeKind::U32 => Type::U32, + TypeKind::U64 => Type::U64, + TypeKind::U128 => Type::U128, TypeKind::Bool => Type::Bool, TypeKind::Void => panic!("Void not a supported type"), TypeKind::Vague(_) => panic!("Tried to compile a vague type!"), diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 42f2b3e..8e09a6a 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -36,12 +36,28 @@ impl From for Metadata { #[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)] pub enum TypeKind { - #[error("i32")] - I32, - #[error("i16")] - I16, #[error("bool")] Bool, + #[error("i8")] + I8, + #[error("i16")] + I16, + #[error("i32")] + I32, + #[error("i64")] + I64, + #[error("i128")] + I128, + #[error("u8")] + U8, + #[error("u16")] + U16, + #[error("u32")] + U32, + #[error("u64")] + U64, + #[error("u128")] + U128, #[error("void")] Void, #[error(transparent)] @@ -71,15 +87,33 @@ impl TypeKind { match self { TypeKind::Void => false, TypeKind::Vague(_) => false, - _ => true, + TypeKind::Bool => false, + TypeKind::I8 => false, + TypeKind::I16 => false, + TypeKind::I32 => false, + TypeKind::I64 => false, + TypeKind::I128 => false, + TypeKind::U8 => false, + TypeKind::U16 => false, + TypeKind::U32 => false, + TypeKind::U64 => false, + TypeKind::U128 => false, } } pub fn is_maths(&self) -> bool { use TypeKind::*; match &self { - I32 => true, + I8 => true, I16 => true, + I32 => true, + I64 => true, + I128 => true, + U8 => true, + U16 => true, + U32 => true, + U64 => true, + U128 => true, Bool => true, Vague(_) => false, Void => false, @@ -89,8 +123,16 @@ impl TypeKind { #[derive(Debug, Clone, Copy)] pub enum Literal { - I32(i32), + I8(i8), I16(i16), + I32(i32), + I64(i64), + I128(i128), + U8(u8), + U16(u16), + U32(u32), + U64(u64), + U128(u128), Vague(VagueLiteral), } @@ -102,8 +144,16 @@ pub enum VagueLiteral { impl Literal { pub fn as_type(self: &Literal) -> TypeKind { match self { - Literal::I32(_) => TypeKind::I32, + Literal::I8(_) => TypeKind::I8, Literal::I16(_) => TypeKind::I16, + Literal::I32(_) => TypeKind::I32, + Literal::I64(_) => TypeKind::I64, + Literal::I128(_) => TypeKind::I128, + Literal::U8(_) => TypeKind::U8, + Literal::U16(_) => TypeKind::U16, + Literal::U32(_) => TypeKind::U32, + Literal::U64(_) => TypeKind::U64, + Literal::U128(_) => TypeKind::U128, Literal::Vague(VagueLiteral::Number(_)) => TypeKind::Vague(VagueType::Number), } } diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index e17b218..e7084e3 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -244,10 +244,26 @@ impl Literal { use Literal as L; use VagueLiteral as VagueL; Ok(match (self, hint) { - (L::I32(_), I32) => self, + (L::I8(_), I8) => self, (L::I16(_), I16) => self, - (L::Vague(VagueL::Number(v)), I32) => L::I32(v as i32), + (L::I32(_), I32) => self, + (L::I64(_), I64) => self, + (L::I128(_), I128) => self, + (L::U8(_), U8) => self, + (L::U16(_), U16) => self, + (L::U32(_), U32) => self, + (L::U64(_), U64) => self, + (L::U128(_), U128) => self, + (L::Vague(VagueL::Number(v)), I8) => L::I8(v as i8), (L::Vague(VagueL::Number(v)), I16) => L::I16(v as i16), + (L::Vague(VagueL::Number(v)), I32) => L::I32(v as i32), + (L::Vague(VagueL::Number(v)), I64) => L::I64(v as i64), + (L::Vague(VagueL::Number(v)), I128) => L::I128(v as i128), + (L::Vague(VagueL::Number(v)), U8) => L::U8(v as u8), + (L::Vague(VagueL::Number(v)), U16) => L::U16(v as u16), + (L::Vague(VagueL::Number(v)), U32) => L::U32(v as u32), + (L::Vague(VagueL::Number(v)), U64) => L::U64(v as u64), + (L::Vague(VagueL::Number(v)), U128) => L::U128(v as u128), // Default type for number literal if unable to find true type. (L::Vague(VagueL::Number(v)), Vague(Number)) => L::I32(v as i32), (_, Vague(_)) => self, @@ -310,8 +326,7 @@ impl Collapsable for TypeKind { (Vague(Number), other) | (other, Vague(Number)) => match other { Vague(Unknown) => Ok(Vague(Number)), Vague(Number) => Ok(Vague(Number)), - I32 => Ok(I32), - I16 => Ok(I16), + I8 | I16 | I32 | I64 | I128 | U8 | U16 | U32 | U64 | U128 => Ok(*other), _ => Err(ErrorKind::TypesIncompatible(*self, *other)), }, (Vague(Unknown), other) | (other, Vague(Unknown)) => Ok(other.clone()),