Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds a bunch of primitive types. #95

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions crates/mun_codegen/src/ir/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,8 @@ impl<'a, 'b, D: IrDatabase> BodyIrGenerator<'a, 'b, D> {
let lhs_type = self.infer[lhs].clone();
let rhs_type = self.infer[rhs].clone();
match lhs_type.as_simple() {
Some(TypeCtor::Float) => self.gen_binary_op_float(lhs, rhs, op),
Some(TypeCtor::Int) => self.gen_binary_op_int(lhs, rhs, op),
Some(TypeCtor::Float(_ty)) => self.gen_binary_op_float(lhs, rhs, op),
Some(TypeCtor::Int(ty)) => self.gen_binary_op_int(lhs, rhs, op, ty.signedness),
_ => unimplemented!(
"unimplemented operation {0}op{1}",
lhs_type.display(self.db),
Expand Down Expand Up @@ -516,6 +516,7 @@ impl<'a, 'b, D: IrDatabase> BodyIrGenerator<'a, 'b, D> {
lhs_expr: ExprId,
rhs_expr: ExprId,
op: BinaryOp,
signedness: hir::Signedness,
) -> Option<BasicValueEnum> {
let lhs = self
.gen_expr(lhs_expr)
Expand All @@ -536,19 +537,43 @@ impl<'a, 'b, D: IrDatabase> BodyIrGenerator<'a, 'b, D> {
CmpOp::Ord {
ordering: Ordering::Less,
strict: false,
} => ("lesseq", IntPredicate::SLE),
} => (
"lesseq",
match signedness {
hir::Signedness::Signed => IntPredicate::SLE,
hir::Signedness::Unsigned => IntPredicate::ULE,
},
),
CmpOp::Ord {
ordering: Ordering::Less,
strict: true,
} => ("less", IntPredicate::SLT),
} => (
"less",
match signedness {
hir::Signedness::Signed => IntPredicate::SLT,
hir::Signedness::Unsigned => IntPredicate::ULT,
},
),
CmpOp::Ord {
ordering: Ordering::Greater,
strict: false,
} => ("greatereq", IntPredicate::SGE),
} => (
"greatereq",
match signedness {
hir::Signedness::Signed => IntPredicate::SGE,
hir::Signedness::Unsigned => IntPredicate::UGE,
},
),
CmpOp::Ord {
ordering: Ordering::Greater,
strict: true,
} => ("greater", IntPredicate::SGT),
} => (
"greater",
match signedness {
hir::Signedness::Signed => IntPredicate::SGT,
hir::Signedness::Unsigned => IntPredicate::UGT,
},
),
};
Some(
self.builder
Expand Down
30 changes: 24 additions & 6 deletions crates/mun_codegen/src/ir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,33 @@ use crate::{
type_info::{TypeGroup, TypeInfo},
IrDatabase,
};
use hir::{ApplicationTy, CallableDef, Ty, TypeCtor};
use hir::{ApplicationTy, CallableDef, FloatBitness, FloatTy, IntBitness, IntTy, Ty, TypeCtor};
use inkwell::types::{AnyTypeEnum, BasicType, BasicTypeEnum, StructType};
use inkwell::AddressSpace;

/// Given a mun type, construct an LLVM IR type
#[rustfmt::skip]
pub(crate) fn ir_query(db: &impl IrDatabase, ty: Ty) -> AnyTypeEnum {
let context = db.context();
match ty {
Ty::Empty => AnyTypeEnum::StructType(context.struct_type(&[], false)),
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
TypeCtor::Float => AnyTypeEnum::FloatType(context.f64_type()),
TypeCtor::Int => AnyTypeEnum::IntType(context.i64_type()),
TypeCtor::Bool => AnyTypeEnum::IntType(context.bool_type()),
// Float primitives
TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => AnyTypeEnum::FloatType(context.f32_type()),
TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => AnyTypeEnum::FloatType(context.f64_type()),
TypeCtor::Float(FloatTy { bitness: FloatBitness::Undefined }) => AnyTypeEnum::FloatType(context.f64_type()),

// Int primitives
TypeCtor::Int(IntTy { bitness: IntBitness::Undefined, .. }) => AnyTypeEnum::IntType(context.i64_type()),
TypeCtor::Int(IntTy { bitness: IntBitness::X8, .. }) => AnyTypeEnum::IntType(context.i8_type()),
TypeCtor::Int(IntTy { bitness: IntBitness::X16, .. }) => AnyTypeEnum::IntType(context.i16_type()),
TypeCtor::Int(IntTy { bitness: IntBitness::X32, .. }) => AnyTypeEnum::IntType(context.i32_type()),
TypeCtor::Int(IntTy { bitness: IntBitness::X64, .. }) => AnyTypeEnum::IntType(context.i64_type()),
TypeCtor::Int(IntTy { bitness: IntBitness::Xsize, .. }) => AnyTypeEnum::IntType(context.i64_type()),

// Boolean
TypeCtor::Bool => AnyTypeEnum::IntType(context.bool_type()),

TypeCtor::FnDef(def @ CallableDef::Function(_)) => {
let ty = db.callable_sig(def);
let params: Vec<BasicTypeEnum> = ty
Expand Down Expand Up @@ -61,8 +75,12 @@ pub fn struct_ty_query(db: &impl IrDatabase, s: hir::Struct) -> StructType {
pub fn type_info_query(db: &impl IrDatabase, ty: Ty) -> TypeInfo {
match ty {
Ty::Apply(ctor) => match ctor.ctor {
TypeCtor::Float => TypeInfo::new("core::float", TypeGroup::FundamentalTypes),
TypeCtor::Int => TypeInfo::new("core::int", TypeGroup::FundamentalTypes),
TypeCtor::Float(ty) => {
TypeInfo::new(format!("core::{}", ty), TypeGroup::FundamentalTypes)
}
TypeCtor::Int(ty) => {
TypeInfo::new(format!("core::{}", ty), TypeGroup::FundamentalTypes)
}
TypeCtor::Bool => TypeInfo::new("core::bool", TypeGroup::FundamentalTypes),
TypeCtor::Struct(s) => TypeInfo::new(s.name(db).to_string(), TypeGroup::StructTypes(s)),
_ => unreachable!("{:?} unhandled", ctor),
Expand Down
19 changes: 19 additions & 0 deletions crates/mun_codegen/src/snapshots/test__primitive_types.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
source: crates/mun_codegen/src/test.rs
expression: "fn add(a: u8, b: u8): u8 { a+b }\n fn less(a: u8, b: u8): bool { a<b }"
---
; ModuleID = 'main.mun'
source_filename = "main.mun"

define i8 @add(i8, i8) {
body:
%add = add i8 %0, %1
ret i8 %add
}

define i1 @less(i8, i8) {
body:
%less = icmp ult i8 %0, %1
ret i1 %less
}

10 changes: 10 additions & 0 deletions crates/mun_codegen/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,16 @@ fn gc_struct() {
)
}

#[test]
fn primitive_types() {
test_snapshot(
r#"
fn add(a: u8, b: u8): u8 { a+b }
fn less(a: u8, b: u8): bool { a<b }
"#,
)
}

fn test_snapshot(text: &str) {
test_snapshot_with_optimization(text, OptimizationLevel::Default);
}
Expand Down
153 changes: 153 additions & 0 deletions crates/mun_hir/src/builtin_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
use crate::name::{name, Name};
use std::fmt;

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Signedness {
Signed,
Unsigned,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum IntBitness {
Xsize,
X8,
X16,
X32,
X64,
Undefined,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum FloatBitness {
X32,
X64,
Undefined,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct BuiltinInt {
pub signedness: Signedness,
pub bitness: IntBitness,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct BuiltinFloat {
pub bitness: FloatBitness,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BuiltinType {
Float(BuiltinFloat),
Int(BuiltinInt),
Bool,
}

impl BuiltinType {
#[rustfmt::skip]
pub const ALL: &'static [(Name, BuiltinType)] = &[
(name![bool], BuiltinType::Bool),

(name![int], BuiltinType::Int(BuiltinInt::INT)),
(name![isize], BuiltinType::Int(BuiltinInt::ISIZE)),
(name![i8], BuiltinType::Int(BuiltinInt::I8)),
(name![i16], BuiltinType::Int(BuiltinInt::I16)),
(name![i32], BuiltinType::Int(BuiltinInt::I32)),
(name![i64], BuiltinType::Int(BuiltinInt::I64)),

(name![uint], BuiltinType::Int(BuiltinInt::UINT)),
(name![usize], BuiltinType::Int(BuiltinInt::USIZE)),
(name![u8], BuiltinType::Int(BuiltinInt::U8)),
(name![u16], BuiltinType::Int(BuiltinInt::U16)),
(name![u32], BuiltinType::Int(BuiltinInt::U32)),
(name![u64], BuiltinType::Int(BuiltinInt::U64)),

(name![float], BuiltinType::Float(BuiltinFloat::FLOAT)),
(name![f32], BuiltinType::Float(BuiltinFloat::F32)),
(name![f64], BuiltinType::Float(BuiltinFloat::F64)),
];
}

impl fmt::Display for BuiltinType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let type_name = match self {
BuiltinType::Bool => "bool",
BuiltinType::Int(BuiltinInt {
signedness,
bitness,
}) => match (signedness, bitness) {
(Signedness::Signed, IntBitness::Xsize) => "isize",
(Signedness::Signed, IntBitness::X8) => "i8",
(Signedness::Signed, IntBitness::X16) => "i16",
(Signedness::Signed, IntBitness::X32) => "i32",
(Signedness::Signed, IntBitness::X64) => "i64",
(Signedness::Signed, IntBitness::Undefined) => "int",

(Signedness::Unsigned, IntBitness::Xsize) => "usize",
(Signedness::Unsigned, IntBitness::X8) => "u8",
(Signedness::Unsigned, IntBitness::X16) => "u16",
(Signedness::Unsigned, IntBitness::X32) => "u32",
(Signedness::Unsigned, IntBitness::X64) => "u64",
(Signedness::Unsigned, IntBitness::Undefined) => "uint",
},
BuiltinType::Float(BuiltinFloat { bitness }) => match bitness {
FloatBitness::X32 => "f32",
FloatBitness::X64 => "f64",
FloatBitness::Undefined => "float",
},
};
f.write_str(type_name)
}
}

#[rustfmt::skip]
impl BuiltinInt {
pub const INT : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::Undefined };
pub const ISIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::Xsize };
pub const I8 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X8 };
pub const I16 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X16 };
pub const I32 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X32 };
pub const I64 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X64 };

pub const UINT : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::Undefined };
pub const USIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize };
pub const U8 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X8 };
pub const U16 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X16 };
pub const U32 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X32 };
pub const U64 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X64 };


pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> {
let res = match suffix {
"isize" => Self::ISIZE,
"i8" => Self::I8,
"i16" => Self::I16,
"i32" => Self::I32,
"i64" => Self::I64,

"usize" => Self::USIZE,
"u8" => Self::U8,
"u16" => Self::U16,
"u32" => Self::U32,
"u64" => Self::U64,

_ => return None,
};
Some(res)
}
}

#[rustfmt::skip]
impl BuiltinFloat {
pub const F32: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X32 };
pub const F64: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X64 };
pub const FLOAT: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::Undefined };

pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> {
let res = match suffix {
"f32" => BuiltinFloat::F32,
"f64" => BuiltinFloat::F64,
_ => return None,
};
Some(res)
}
}
18 changes: 1 addition & 17 deletions crates/mun_hir/src/code_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ pub(crate) mod src;

use self::src::HasSource;
use crate::adt::{StructData, StructFieldId};
use crate::builtin_type::BuiltinType;
use crate::code_model::diagnostics::ModuleDefinitionDiagnostic;
use crate::diagnostics::DiagnosticSink;
use crate::expr::validator::ExprValidator;
use crate::expr::{Body, BodySourceMap};
use crate::ids::AstItemDef;
use crate::ids::LocationCtx;
use crate::name::*;
use crate::name_resolution::Namespace;
use crate::raw::{DefKind, RawFileItem};
use crate::resolve::{Resolution, Resolver};
Expand Down Expand Up @@ -338,22 +338,6 @@ impl Function {
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BuiltinType {
Float,
Int,
Boolean,
}

impl BuiltinType {
#[rustfmt::skip]
pub(crate) const ALL: &'static [(Name, BuiltinType)] = &[
(FLOAT, BuiltinType::Float),
(INT, BuiltinType::Int),
(BOOLEAN, BuiltinType::Boolean),
];
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Struct {
pub(crate) id: StructId,
Expand Down
4 changes: 3 additions & 1 deletion crates/mun_hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod macros;
#[macro_use]
mod arena;
mod adt;
mod builtin_type;
mod code_model;
mod db;
pub mod diagnostics;
Expand Down Expand Up @@ -40,6 +41,7 @@ pub use relative_path::{RelativePath, RelativePathBuf};

pub use crate::{
arena::{ArenaId, RawId},
builtin_type::{FloatBitness, IntBitness, Signedness},
db::{
DefDatabase, DefDatabaseStorage, HirDatabase, HirDatabaseStorage, SourceDatabase,
SourceDatabaseStorage,
Expand All @@ -56,7 +58,7 @@ pub use crate::{
path::{Path, PathKind},
raw::RawItems,
resolve::{Resolution, Resolver},
ty::{lower::CallableDef, ApplicationTy, InferenceResult, Ty, TypeCtor},
ty::{lower::CallableDef, ApplicationTy, FloatTy, InferenceResult, IntTy, Ty, TypeCtor},
};

use crate::{
Expand Down
Loading