Add all types u8 -> i128 and fix signedness in icmp
This commit is contained in:
parent
14283afe59
commit
46560d8541
@ -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,
|
||||
}
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -15,7 +15,17 @@ impl Parse for Type {
|
||||
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
||||
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 {
|
||||
|
@ -168,7 +168,17 @@ impl ast::Literal {
|
||||
impl From<ast::TypeKind> 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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!"),
|
||||
|
@ -36,12 +36,28 @@ impl From<TokenRange> 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),
|
||||
}
|
||||
}
|
||||
|
@ -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()),
|
||||
|
Loading…
Reference in New Issue
Block a user