Add all types u8 -> i128 and fix signedness in icmp

This commit is contained in:
Sofia 2025-07-08 23:47:44 +03:00
parent 14283afe59
commit 46560d8541
10 changed files with 191 additions and 31 deletions

View File

@ -260,9 +260,17 @@ impl ConstValue {
pub fn get_type(&self) -> Type { pub fn get_type(&self) -> Type {
use Type::*; use Type::*;
match self { match self {
ConstValue::I32(_) => I32, ConstValue::I8(_) => I8,
ConstValue::I16(_) => I16, ConstValue::I16(_) => I16,
ConstValue::I32(_) => I32,
ConstValue::I64(_) => I64,
ConstValue::I128(_) => I128,
ConstValue::U8(_) => U8,
ConstValue::U16(_) => U16,
ConstValue::U32(_) => U32, ConstValue::U32(_) => U32,
ConstValue::U64(_) => U64,
ConstValue::U128(_) => U128,
ConstValue::Bool(_) => Bool,
} }
} }
} }
@ -270,9 +278,16 @@ impl ConstValue {
impl Type { impl Type {
pub fn comparable(&self) -> bool { pub fn comparable(&self) -> bool {
match self { match self {
Type::I32 => true, Type::I8 => true,
Type::I16 => true, Type::I16 => true,
Type::I32 => true,
Type::I64 => true,
Type::I128 => true,
Type::U8 => true,
Type::U16 => true,
Type::U32 => true, Type::U32 => true,
Type::U64 => true,
Type::U128 => true,
Type::Bool => true, Type::Bool => true,
Type::Void => false, Type::Void => false,
} }
@ -280,9 +295,16 @@ impl Type {
pub fn signed(&self) -> bool { pub fn signed(&self) -> bool {
match self { match self {
Type::I32 => true, Type::I8 => true,
Type::I16 => true, Type::I16 => true,
Type::I32 => true,
Type::I64 => true,
Type::I128 => true,
Type::U8 => false,
Type::U16 => false,
Type::U32 => false, Type::U32 => false,
Type::U64 => false,
Type::U128 => false,
Type::Bool => false, Type::Bool => false,
Type::Void => false, Type::Void => false,
} }

View File

@ -264,12 +264,13 @@ impl InstructionHolder {
LLVMBuildSub(module.builder_ref, lhs_val, rhs_val, c"sub".as_ptr()) LLVMBuildSub(module.builder_ref, lhs_val, rhs_val, c"sub".as_ptr())
} }
ICmp(pred, lhs, rhs) => { 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; let rhs_val = module.values.get(&rhs).unwrap().value_ref;
LLVMBuildICmp( LLVMBuildICmp(
module.builder_ref, module.builder_ref,
pred.as_llvm(_ty.signed()), // Signedness from LHS
lhs_val, pred.as_llvm(lhs._ty.signed()),
lhs.value_ref,
rhs_val, rhs_val,
c"icmp".as_ptr(), c"icmp".as_ptr(),
) )
@ -370,9 +371,17 @@ impl ConstValue {
unsafe { unsafe {
let t = self.get_type().as_llvm(context); let t = self.get_type().as_llvm(context);
match *self { 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::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 { impl Type {
fn as_llvm(&self, context: LLVMContextRef) -> LLVMTypeRef { fn as_llvm(&self, context: LLVMContextRef) -> LLVMTypeRef {
use Type::*;
unsafe { unsafe {
match self { match self {
Type::I32 => LLVMInt32TypeInContext(context), I8 | U8 => LLVMInt8TypeInContext(context),
Type::I16 => LLVMInt16TypeInContext(context), I16 | U16 => LLVMInt16TypeInContext(context),
Type::U32 => LLVMInt32TypeInContext(context), I32 | U32 => LLVMInt32TypeInContext(context),
Type::Bool => LLVMInt1TypeInContext(context), I64 | U64 => LLVMInt64TypeInContext(context),
Type::Void => LLVMVoidType(), I128 | U128 => LLVMInt128TypeInContext(context),
Bool => LLVMInt1TypeInContext(context),
Void => LLVMVoidType(),
} }
} }
} }

View File

@ -158,18 +158,33 @@ pub enum InstructionKind {
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub enum Type { pub enum Type {
I32, I8,
I16, I16,
I32,
I64,
I128,
U8,
U16,
U32, U32,
U64,
U128,
Bool, Bool,
Void, Void,
} }
#[derive(Debug, Clone, Hash)] #[derive(Debug, Clone, Hash)]
pub enum ConstValue { pub enum ConstValue {
I32(i32), I8(i8),
I16(i16), I16(i16),
I32(i32),
I64(i64),
I128(i128),
U8(u8),
U16(u16),
U32(u32), U32(u32),
U64(u64),
U128(u128),
Bool(bool),
} }
#[derive(Clone, Hash)] #[derive(Clone, Hash)]

View File

@ -1,11 +1,11 @@
// Main // Main
fn main() -> i32 { fn main() -> u8 {
let a = fibonacci(3); let a = fibonacci(3);
return a; return a;
} }
// Fibonacci // Fibonacci
fn fibonacci(value: i32) -> i32 { fn fibonacci(value: u8) -> u8 {
if value < 3 { if value < 3 {
return 1; return 1;
} }

View File

@ -8,7 +8,17 @@ pub struct Type(pub TypeKind, pub TokenRange);
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum TypeKind { pub enum TypeKind {
Bool,
I8,
I16,
I32, I32,
I64,
I128,
U8,
U16,
U32,
U64,
U128,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View File

@ -15,7 +15,17 @@ impl Parse for Type {
fn parse(mut stream: TokenStream) -> Result<Self, Error> { fn parse(mut stream: TokenStream) -> Result<Self, Error> {
let kind = if let Some(Token::Identifier(ident)) = stream.next() { let kind = if let Some(Token::Identifier(ident)) = stream.next() {
Ok(match &*ident { Ok(match &*ident {
"bool" => TypeKind::Bool,
"i8" => TypeKind::I8,
"i16" => TypeKind::I16,
"i32" => TypeKind::I32, "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"), _ => panic!("asd"),
}) })
} else { } else {

View File

@ -168,7 +168,17 @@ impl ast::Literal {
impl From<ast::TypeKind> for mir::TypeKind { impl From<ast::TypeKind> for mir::TypeKind {
fn from(value: ast::TypeKind) -> Self { fn from(value: ast::TypeKind) -> Self {
match value { 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::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,
} }
} }
} }

View File

@ -323,8 +323,16 @@ impl mir::Literal {
pub fn as_const_kind(&self) -> InstructionKind { pub fn as_const_kind(&self) -> InstructionKind {
InstructionKind::Constant(match *self { 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::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!"), mir::Literal::Vague(_) => panic!("Got vague literal!"),
}) })
} }
@ -333,8 +341,16 @@ impl mir::Literal {
impl TypeKind { impl TypeKind {
fn get_type(&self) -> Type { fn get_type(&self) -> Type {
match &self { match &self {
TypeKind::I32 => Type::I32, TypeKind::I8 => Type::I8,
TypeKind::I16 => Type::I16, 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::Bool => Type::Bool,
TypeKind::Void => panic!("Void not a supported type"), TypeKind::Void => panic!("Void not a supported type"),
TypeKind::Vague(_) => panic!("Tried to compile a vague type!"), TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),

View File

@ -36,12 +36,28 @@ impl From<TokenRange> for Metadata {
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)] #[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
pub enum TypeKind { pub enum TypeKind {
#[error("i32")]
I32,
#[error("i16")]
I16,
#[error("bool")] #[error("bool")]
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")] #[error("void")]
Void, Void,
#[error(transparent)] #[error(transparent)]
@ -71,15 +87,33 @@ impl TypeKind {
match self { match self {
TypeKind::Void => false, TypeKind::Void => false,
TypeKind::Vague(_) => 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 { pub fn is_maths(&self) -> bool {
use TypeKind::*; use TypeKind::*;
match &self { match &self {
I32 => true, I8 => true,
I16 => true, I16 => true,
I32 => true,
I64 => true,
I128 => true,
U8 => true,
U16 => true,
U32 => true,
U64 => true,
U128 => true,
Bool => true, Bool => true,
Vague(_) => false, Vague(_) => false,
Void => false, Void => false,
@ -89,8 +123,16 @@ impl TypeKind {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum Literal { pub enum Literal {
I32(i32), I8(i8),
I16(i16), I16(i16),
I32(i32),
I64(i64),
I128(i128),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
U128(u128),
Vague(VagueLiteral), Vague(VagueLiteral),
} }
@ -102,8 +144,16 @@ pub enum VagueLiteral {
impl Literal { impl Literal {
pub fn as_type(self: &Literal) -> TypeKind { pub fn as_type(self: &Literal) -> TypeKind {
match self { match self {
Literal::I32(_) => TypeKind::I32, Literal::I8(_) => TypeKind::I8,
Literal::I16(_) => TypeKind::I16, 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), Literal::Vague(VagueLiteral::Number(_)) => TypeKind::Vague(VagueType::Number),
} }
} }

View File

@ -244,10 +244,26 @@ impl Literal {
use Literal as L; use Literal as L;
use VagueLiteral as VagueL; use VagueLiteral as VagueL;
Ok(match (self, hint) { Ok(match (self, hint) {
(L::I32(_), I32) => self, (L::I8(_), I8) => self,
(L::I16(_), I16) => 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)), 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. // Default type for number literal if unable to find true type.
(L::Vague(VagueL::Number(v)), Vague(Number)) => L::I32(v as i32), (L::Vague(VagueL::Number(v)), Vague(Number)) => L::I32(v as i32),
(_, Vague(_)) => self, (_, Vague(_)) => self,
@ -310,8 +326,7 @@ impl Collapsable for TypeKind {
(Vague(Number), other) | (other, Vague(Number)) => match other { (Vague(Number), other) | (other, Vague(Number)) => match other {
Vague(Unknown) => Ok(Vague(Number)), Vague(Unknown) => Ok(Vague(Number)),
Vague(Number) => Ok(Vague(Number)), Vague(Number) => Ok(Vague(Number)),
I32 => Ok(I32), I8 | I16 | I32 | I64 | I128 | U8 | U16 | U32 | U64 | U128 => Ok(*other),
I16 => Ok(I16),
_ => Err(ErrorKind::TypesIncompatible(*self, *other)), _ => Err(ErrorKind::TypesIncompatible(*self, *other)),
}, },
(Vague(Unknown), other) | (other, Vague(Unknown)) => Ok(other.clone()), (Vague(Unknown), other) | (other, Vague(Unknown)) => Ok(other.clone()),